VC6で作った関数をDLL化し、
それをVB2005で使用したいと思っております。
DllImportを使用しております。
Dll側の関数にint型の引数を値渡し参照渡しするのには問題はございませんでした。
しかし、構造体配列を参照渡しするとエラーが発生し終了してしまいます。
自分なりに調べていろいろとしているのですが、同じようなケースが見つからず、
四苦八苦しております。
おそらくは、構造体のメンバのマーシャリングあたりがおかしいのかと思っておりますが、どうもうまくいきません。
よろしければ、おかしいところをご指摘いただけませんでしょうか。
以下に、dll側(VC6)と呼び出し側(VB2005)のソース、エラーメッセージを記載いたします。
// DLL側(VC6) //
typedef struct config_tag{
char SrvIP1[32];
char SrvIP2[32];
char SrvPort[32];
char SrvName1[32];
char SrvName2[32];
int nLogFlag;
int nTransPeriodic;
} config_str;
int __stdcall StructFunc2( config_tag *cnf_str);
int __stdcall StructFunc2( config_str *structure)
{
char cbuf[5][32] = {"192.168.11.1",
"192.168.11.2",
"1234",
"Server1",
"Server2"
};
int ibuf[2] = {1,2};
int i;
for( i=0; i<5; i++)
{
strcpy(structure[i].SrvIP1, cbuf[0]);
strcpy(structure[i].SrvIP2, cbuf[1]);
strcpy(structure[i].SrvPort, cbuf[2]);
strcpy(structure[i].SrvName1, cbuf[3]);
strcpy(structure[i].SrvName2, cbuf[4]);
structure[i].nLogFlag = ibuf[0];
structure[i].nTransPeriodic = ibuf[1];
}
return MessageBox(NULL, "引数として渡された構造体 config_tag にセットしました。","DLL側",0);
}
// 呼び出し側(VB2005)
**** module *********************
<StructLayout(LayoutKind.Sequential)> _
Public Structure config_tag
<VBFixedString(32), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=32)> Public SrvIP1 As String
<VBFixedString(32), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=32)> Public SrvIP2 As String
<VBFixedString(32), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=32)> Public SrvPort As String
<VBFixedString(32), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=32)> Public SrvName1 As String
<VBFixedString(32), System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst:=32)> Public SrvName2 As String
Public nLogFlag As Integer
Public nTransPeriodic As Integer
End Structure
Module Module1
<DllImport("DllTest.dll")> _
Public Function StructFunc2(ByRef str_conf() As config_tag) As Integer
End Function
End Module
************************************
Public Class Form1
Private Sub Command1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click
Dim str_conf(4) As config_tag
Call StructFunc2(str_conf)
End Sub
End Class
****** エラーメッセージ ************
マネージ デバッグ アシスタント 'PInvokeStackImbalance' では 'D:\VB_UseDll\WindowsApplication1\bin\Debug\WindowsApplication1.vshost.exe' に問題を検出しました。
追加情報: PInvoke 関数 'WindowsApplication1!WindowsApplication1.Module1::StructFunc2' がスタックを不安定にしています。PInvoke シグネチャがアンマネージ ターゲット シグネチャに一致していないことが原因として考えられます。呼び出し規約、および PInvoke シグネチャのパラメータがターゲットのアンマネージ シグネチャに一致していることを確認してください。
******************************************
構造体の引数をLongに変えたり、構造体メンバのマーシャリングをはずしたりしてみましたが、うまくいきませんでした。
構造体の先頭アドレスの渡し方がおかしいのかと思って、
宣言
Public Function StructFunc2(ByRef str_conf As config_tag) As Integer
呼び出し
Call StructFunc2(str_conf(0))
と、してみましたがだめでした。
上記のエラーメッセージは
Dll側で出しているメッセージボックス(・・・セットしました。)が出て、OKをクリックした後にでます。
よろしければ、ご教授お願い致します。
http://msdn2.microsoft.com/ja-jp/library/sd10k43k(VS.80).aspx
相互運用に手を出すなら熟読してください。
各種サンプルも載っています。もちろん、構造体配列を渡すようなサンプルも。
>>HongLiang様
ご返答ありがとうございました。
どうやら、簡単にいくようなものではないようですね。
一応その辺は読んだつもりだったのですが、もう一度しっかりと熟読してみます。
現在も読みながら色々と変更を加えておりますがうまくいっておりません。
急ぎなのでゆっくりと読んでいる時間がないのですが・・・
ありがとうございました。
ツイート | ![]() |