3

ネイティブ C dll に次のコードがあります。

typedef void CallbackType( INT32 param1, INT32 param2 );

NATIVE_API void RegisterEventCallBack(CallbackType *callBackFunction);


//INT32 is defined as below:

typedef signed int          INT32, *PINT32;

C# コードからこのメソッドを呼び出す必要があります。stackflow で利用可能ないくつかのソリューションを実行した後、これを試しました。

委任の宣言:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CallbackType(Int32 param1, Int32 param2); 

メソッドのインポート宣言:

[DllImport("EtIPAdapter.dll")]
public static extern void RegisterEventCallBack([MarshalAs(UnmanagedType.FunctionPtr)]CallbackType callbackFunc);

呼び出し:

RegisterEventCallBack(ReceivedData);

private static void ReceivedData(Int32 param1, Int32 param2)
{
    //Do something
}

しかし、これは機能せず、次のエラーが表示されます。

PInvoke 関数 'RegisterEventCallBack' の呼び出しにより、スタックのバランスが崩れています。これは、マネージド PInvoke 署名がアンマネージド ターゲット シグネチャと一致しないことが原因である可能性があります。PInvoke シグネチャの呼び出し規約とパラメーターがターゲットのアンマネージド シグネチャと一致することを確認します。

で取得した関数ポインタも渡してみましたGetFunctionPointerFromDelegate(ReceivedDataDelegate)。しかし、それも同じエラーになります。

エラーは署名の不一致を指摘していますが、明らかな署名の不一致は見られません。助けてください。

4

1 に答える 1

1

DLLImport を実行するときは、呼び出し規約を確認してください。これはデフォルトで Winapi / StdCall になります。
また、ガベージ コレクターはマネージド コード内の参照しかカウントできないため、ガベージ コレクターはしばらくするとデリゲートを削除するため、アプリケーションの有効期間中はマネージド コード内にデリゲートへの参照を保持する必要があります。私は通常、デリゲートを設定するクラスの静的プロパティとしてデリゲートへの参照を保持します。

于 2013-04-09T10:24:10.837 に答える