VB 文字列は、OLE ドキュメントでは BSTR と呼ばれ、LPWSTR とほぼ互換性があります。これらは 1 文字あたり 2 バイトの Unicode (UTF-16) 文字列で null で終了しますが、文字列ポインターが指すメモリの直前に 32 ビットの長さがあります。
コードは LPSTR* を使用します。これは、1 文字あたり 1 バイトの ANSI 文字列へのポインターへのポインターです。明らかに、文字列を VB6 コードに返すためにこれを行っています。
残念ながら、この 2 つは互換性がありません。
コードがクラッシュする理由は、VB6 変数 <mystr> を関数に渡しているためですが、デフォルトでは次のように vbNullString に設定されています。
BSTR mystr = NULL;
しかし、あなたの主な問題は、VB が C 関数を記述どおりに使用できない可能性があることです。LPSTR* の Declare ステートメントを記述する方法はありません。Cコードを次のように変更した場合
include “windows.h”
Int __stdcall WritestStr(LPSTR mystr)
{
const LPSTR myconststr = “Venancio Guedes”;
if (mystr)
int destlen = strlen(mystr);
int srclen = strlen(myconststr);
if (destlen >= srclen)
{
strcpy(mystr, myconststr);
return 0;
}
return srclen;
}
...宣言を次のように変更できます。
Private Declare Function WritestStr Lib “teststr.dll” (ByVal mystr As String) As Long
...そして、文字列を受け入れるバッファを宣言してください。LPSTR の Declare ステートメントを作成することもできますが、それを行う必要があります。
Private Sub command1_Click()
Dim mystr As string
Dim nLen As Long
mystr = Space$(1024)
nLen = WritestStr(mystr)
Msgbox Left$(mystr, nLen)
End Sub
これは、ほとんどの Win32 API 関数がどのように機能するかを非常に連想させます。
mystr を ByVal として渡すと、<mystr> を BSTR から一時的な LPSTR にコピーし、そのバッファーへのポインターを渡す必要があることが VB6 に通知されます。WriteStr() の実行が完了すると、LPSTR バッファーを元の BSTR にコピーします。
関数に渡す VB 文字列バッファー <mystr> を割り当てると、何かを書き戻すことができます。
または、C プログラムを書き直して、BSTR をネイティブに受け入れるようにすることもできます (多言語が必要な場合は、最もクリーンで移植性の高いソリューションです)。その場合、元の VB6 宣言は、つまり ByRef mystr As String になります。残念ながら、ここで行っているように、まだバッファに書き込む必要があります。
LPWSTR*、LPSTR*、または BSTR* が必要な場合は、タイプ ライブラリで関数を宣言する必要があります。これについては、ここで説明する時間がありません。