回答編集履歴

3

VB6 に文字列を戻すときは SysAllocStringByteLen を使う

2023/09/22 08:03

投稿

KOZ6.0
KOZ6.0

スコア2661

test CHANGED
@@ -44,8 +44,8 @@
44
44
  __declspec(dllexport) BSTR WINAPI SendMail(
45
45
  BSTR* sServer, BSTR* sTo, BSTR* sFrom,
46
46
  BSTR* sSubject, BSTR* sBody, BSTR* sFile) {
47
-
47
+ char buf[] = "this is a pen";
48
- return ::SysAllocString((OLECHAR*)"this is a pen");
48
+ return SysAllocStringByteLen(buf, lstrlenA(buf));
49
49
  }
50
50
  }
51
51
  ```

2

VB6側は変更できないというのを見落としていたので

2023/09/21 20:51

投稿

KOZ6.0
KOZ6.0

スコア2661

test CHANGED
@@ -19,3 +19,42 @@
19
19
  VB6 なので、32bit だけで良いのですが、ここで注意事項。
20
20
 
21
21
  Visual Studio 2019 までは 32bit だったので、ビルドすると 32bit の COM として登録されますが、2020 は 64bit なので 64bit の COM として登録されるので手動で登録する必要があります。
22
+
23
+ ---
24
+
25
+ ### 追記:VB6側は変更できないというのを見落としていたので
26
+
27
+ 前述したとおり、C# は基本的にレガシー DLL を作成できません。
28
+ なので、C# の DLL を呼び出したいのであれば、C++/CLR でラッパー DLL を作ることになるでしょう。
29
+
30
+ VB6 → C++/CLR → C# という感じで呼び出すわけですね。
31
+
32
+ VB の宣言が
33
+
34
+ ```vb
35
+ Private Declare Function SendMail Lib "smtpmail" _
36
+ (sServer As String, sTo As String, sFrom As String, _
37
+ sSubject As String, sBody As String, sFile As String) As String
38
+ ```
39
+
40
+ のようになっているので C++/CLR 側は
41
+
42
+ ```c++
43
+ extern "C" {
44
+ __declspec(dllexport) BSTR WINAPI SendMail(
45
+ BSTR* sServer, BSTR* sTo, BSTR* sFrom,
46
+ BSTR* sSubject, BSTR* sBody, BSTR* sFile) {
47
+
48
+ return ::SysAllocString((OLECHAR*)"this is a pen");
49
+ }
50
+ }
51
+ ```
52
+
53
+ という感じになるかと思います。
54
+
55
+ 文字列は BSTR で渡されますが、困ったことに VB 側が Unicode から Ansi に変換してしまいます。
56
+
57
+ ですから、Ansi → Unicode の変換を行ってから C# の DLL を呼び出す必要があります。
58
+
59
+ 逆に C# から渡された文字列は、Unicode から Ansi への変換を行ってから VB6 に戻す必要があります。
60
+

1

おすすめと注意事項

2023/09/21 05:08

投稿

KOZ6.0
KOZ6.0

スコア2661

test CHANGED
@@ -9,3 +9,13 @@
9
9
 
10
10
  どこかの偉い人がレガシー dll として作る方法を提供していますが、裏技なのでお勧めしません。
11
11
 
12
+
13
+ おすすめのページです。
14
+
15
+ 「C# で COM オブジェクトを作ってみる」
16
+ https://qiita.com/tomochan154/items/1ce33f2aef167c0fed9d
17
+
18
+ AnyCPU でビルドすると、32bit/64bit 双方で動く dll になるようです。
19
+ VB6 なので、32bit だけで良いのですが、ここで注意事項。
20
+
21
+ Visual Studio 2019 までは 32bit だったので、ビルドすると 32bit の COM として登録されますが、2020 は 64bit なので 64bit の COM として登録されるので手動で登録する必要があります。