VC++で作成したDLL内の関数に、VBAよりString型変数のアドレスを渡して、
そのString型変数に文字列を設定したいのですが、うまくいきません。
VBA側:
言語 Access 2000 VBA
コード
Declare Function GetNezumi Lib "dll1" (ByVal intKind As Integer, ByVal strAaa As String)
Private Sub Test()
Dim lngRet As Long
Dim strAaa As String
Dim intKind As Integer
intKind = 1
lngRet = GetNezumi(intKind, StrPtr(strAaa))
end sub
VC側:
言語 Visual C++ 6.0
DLLのタイプ MFCレギュラーDLL
コード
extern "C" int WINAPI GetNezumi(int intKind, char* strAaa)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// 通常関数の本体はこの位置にあります
if (intKind == 1) {
strcpy(strAaa, "nezumi_1"):
} else {
strcpy(strAaa, "nezumi_2"):
}
return 0;
}
これで、VBA側でデバック実行すると、strAaaには何も設定されていません。
一応下記等を参照しましたが、結局、本質問の場合どうしたらよいかわかりません。
http://www.ne.jp/asahi/hishidama/home/tech/excel/dll.html
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200411/04110109.txt
アドバイスをお願いします。
ちょろねずみ さん こんにちは。
誰も(VB側もVC側も)、文字列の領域を確保していないからでは?
それから、
> Declare Function GetNezumi Lib "dll1" (ByVal intKind As Integer, ByVal strAaa As String)
と宣言しているのに、
> lngRet = GetNezumi(intKind, StrPtr(strAaa))
こんなことやっても無意味(大間違い)なのでは?
> strAaa=Space(100)
> lngRet = GetNezumi(intKind, strAaa)
とかでよいのでは?
大吉末吉さん、返答ありがとうございます。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200411/04110109.txt
をよく読むと
http://support.microsoft.com/default.aspx?scid=kb;ja;410837
がありました。
ここに、構造体の引き渡しと、 DLL 内での文字列書き換えの サンプル が
ありました。こいつでやるとうまくいきました。
>Declare Function GetNezumi Lib "dll1" (ByVal intKind As Integer, ByVal strAaa As String)
このような宣言であれば、大吉末吉さんのおっしゃるとおり、
VB側で文字列を作って渡すのが普通です。
戻り値として返したり、String型として処理させるのであれば、
SysAllocStringやSysAllocStringLenghtを使います。
(CStringにもAllocSysStringって関数があります。)
ここら辺は、VB掲示板及びVC掲示板の過去ログ検索で
SysAllocStringをキーワードに検索してみればたくさん参考になりそうなのが見つかります。
(私も、なんどか回答しています。)
ツイート | ![]() |