- - PR -
[C#] 引数にcallbackを持つDLLメソッドの使用について
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-06-17 16:05
はじめまして。
C++builderで作成されたDLLをVC#で利用しているのですが、その中に 引数の一つにcallbackを持つメソッドがあります。 ヘルプの「Callback のサンプル」の情報を参照して作成、動作確認したところ DLLのメソッドで指定したcallbackが呼ばれるまでは動作しているのですが そのcallback終了時に下記のエラーメッセージボックスが出て、callbackが無限に 繰り返されてしまいます。(当然エラーメッセージも繰り返されます。) The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different convention. 下記のようなコードを書いたのですが、何かの指定が不足しているのでしょうか。 呼び出し規約が間違えているとこのメッセージが出るという情報をどこかで見たのですが・・・ public class LibWrap { // delegate public delegate void funcPtr( int nA, int nB ); [DllImport("Hoge.dll")] public extern static int HogeHoge( string pcName, // char * string pcTargetName, // char * System.IntPtr pData, // void * funcPtr funcCB // void (*Callback)(int nA, int nB) ); } public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Button button1; private System.ComponentModel.Container components = null; LibWrap.funcPtr funcCB; (中略) // CallBack用 private static void CallBack( int nA, int nB ) { return; } unsafe private void button1_Click(object sender, System.EventArgs e) { byte[] buf = new byte[5]; buf[0] = 0x41; buf[1] = 0x42; buf[2] = 0x43; buf[3] = 0x44; funcCB = new LibWrap.funcPtr( Form1.CallBack ); fixed( byte *byp = &buf[0] ) { System.IntPtr pBuf = new System.IntPtr( byp ); LibWrap.HogeHoge("app", "targ", pBuf, funcCB ); } } } [ メッセージ編集済み 編集者: ふぉる 編集日時 2004-06-17 16:09 ] | ||||||||
|
投稿日時: 2004-06-18 07:31
スタックフレームが壊れていますね。 呼び出し規約があってないんでしょう。 [DllImport("Hoge.dll",CallingConvention=XXX)] public extern static int HogeHoge の XXX のところを適切な値に置き換えて調節してください。 _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://hidori.jp/ // Microsoft MVP for Visual C# // // @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/ | ||||||||
|
投稿日時: 2004-06-18 12:25
お返事ありがとうございます。
CallingConvention については既に試してあるのですが、cdecl,thiscall いずれを指定して実行しても問題は解決されない状態です。 | ||||||||
|
投稿日時: 2004-06-18 12:56
C++Builder側の宣言はどうなっていますか?
__fastcallは付いていませんよね? | ||||||||
|
投稿日時: 2004-06-18 15:43
DLL側の宣言は下記のようになっています。
#define EXPORTDLL extern "C" __declspec(dllexport) EXPORTDLL long __stdcall HogeHoge( char* pcName, char* pcTargetName, void *pData, void (*Callback)(int nA, int nB) ); | ||||||||
|
投稿日時: 2004-06-18 16:19
delegate の方の呼び出し規約を調整する必要がありますね。 _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://hidori.jp/ // Microsoft MVP for Visual C# // // @IT会議室 RSS 配信中: http://hidori.jp/rss/atmarkIT/ | ||||||||
|
投稿日時: 2004-06-18 20:42
すみません。それは具体的にどのように記述するのでしょうか。 [DllImport("Hoge.dll",CallingConvention=CallingConvention.StdCall)] という記述では直りませんでしたし | ||||||||
|
投稿日時: 2004-06-18 21:40
の Callback の呼び出し規約を指定しなければならないはずなんですが、具体的にどうすればいいかは私は分かりません。
の XXX の位置で属性で指定するだとは思いますが、まさか、Win32 API にコールバック関数を与えることしか考えていなくて、引数としての関数ポインタの呼び出し規約を指定する方法が無かったりして。。。 元プログラムの修正が可能であれば、Callback の呼び出し規約を通常の Win32 API と同じ __stdcall すれば、C# 側のコードで特に何も対応をしなくても通るはずです。 _________________ // 渋木宏明 (Hiroaki SHIBUKI) // http://www.hidori.jp/ // Microsoft MVP for Visual Developer - C# since 2004 [ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2004-06-18 22:55 ] |