私は基本的にコールバックのためにC#代理人を書く方法を理解していると思いますが、これは私を混乱させます。C#コールバックの代理人
typedef int (__stdcall* Callback)(
long lCode,
long lParamSize,
void* pParam
);
と私のC#のアプローチは、次のようになります: C++の定義は以下のとおりである
unsafe delegate int CallbackDelegate (int lCode, int lParamSize, IntPtr pParam);
これは正しくないと思われるが、私は、デリゲートの私の定義を意味PInvokeStackInbalanceエラーを取得しますので、間違っている。
関数の残りのパラメータは文字列またはintです。つまり、エラーを引き起こすことはありません。また、デリゲートの代わりにIntPtr.Zeroを渡すだけであれば(つまり、既存のコールバック関数)AccessViolationエラーが発生します。
私は間違っていますか?
EDIT:
完全なC++機能は次のとおりです。
int
__stdcall
_Initialize (
const char* FileName,
Callback cbFunction,
int Code,
const char* Name,
unsigned int Option,
unsigned int Option2
);
私のC#のバージョンは次のとおりです。
関数は(テストのために)ただのメインルーチンの内部で呼び出され[DllImport("MyDll.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int _Initialize (string FileName, CallbackDelegate cbFunction, int Code, string Name, uint Options, uint Options2);
コンソールアプリケーション:
static void Main(string[] args)
{
CallbackDelegate del = new CallbackDelegate(onCallback);
Console.Write(_Initialize("SomeFile.dat", del, 1000, "", 0, 4));
Console.Read();
}
その後、私が代わりにデリゲートの
IntPtr.Zero
を渡した場合、私は、私は
_Initialize
を呼び出す行に
PInvokeStackInbalance
エラーを取得します
static int onCallback(int lCode, int lParamSize, IntPtr pParam)
{
return 0;
}
、およびIntPtr
の代わりCallbackDelegate
に関数の定義を変更:onCallback
はこれです0
私はAccessViolationException
を得る。
'関数のパラメータの残りの部分をしています文字列またはints'です。情報を隠さないでください。 –
安全でないことを試しましたか?すなわち、デリゲートint CallbackDelegate(int lCode、int lParamSize、IntPtr pParam); – DougEC
@HansPassant私は情報を隠そうとしていない、私は関連性のないものを捨てようとしていた。質問を編集して情報を追加します。 – Valandur