3

I have the following code in Native 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;

I have to call this method from my C# code. After following some solutions available at stackflow, I tried this:

Declaration of delegate:

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

Method import declaration:

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

Calling:

RegisterEventCallBack(ReceivedData);

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

But this doesn't work and I get the following error:

A call to PInvoke function 'RegisterEventCallBack' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

I also tried by passing the function pointer which I got using GetFunctionPointerFromDelegate(ReceivedDataDelegate). But that also result in the same error.

Error point out to signature mismatch, but I don't see any obvious signature mismatch. Please help.

2
  • You can try the following declaration in link: stackoverflow.com/a/9855516/2253250 also should check is function prototype correct? nirsoft.net/utils/dll_export_viewer.html can use DllExport Viewer. Commented Apr 9, 2013 at 10:20
  • 1
    How is the NATIVE_API macro defined? I think the problem is with your managed declaration of the RegisterEventCallBack function, not the callback delegate. Are you using the right calling convention? It seems odd that RegisterEventCallBack would use stdcall (the default for DllImport) when its callback parameter uses cdecl. Commented Apr 9, 2013 at 10:23

1 Answer 1

1

Please check the calling convention when doing the DLLImport - this defaults to Winapi / StdCall.
Also it is important that you must keep a reference to your delegate inside the managed code during the lifetime of the application as the garbage collector will otherwise remove your delegate after a while, because the garbage collector can only count references inside the managed code. I usually keep a reference to the delegate as a static property of the class which setups the delegate.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. changing the DLLImport naming convention to "cdecl" worked. [DllImport("EtIPAdapter.dll",CallingConvention=CallingConvention.Cdecl)] public static extern void RegisterEventCallBack([MarshalAs(UnmanagedType.FunctionPtr)]LogEventCallbackType pfnLogEvent);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.