I'm calling an external C library from a C# wrapper that I'm writing. One of the functions I'm calling is to register a callback function. I get no errors when I call the setCallback function but when the callback function is later called I get errors, unfortunately unspecified by the C library.
Here's the C method (from the header file)
DLLExport int setCallbacks(Client handle, void* context, connectionLost* cl, messageArrived* ma, deliveryComplete* dc); Here's my C# declaration of the method
[DllImport("some.dll", CharSet = CharSet.Auto, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl)] private static extern int setCallbacks(IntPtr client, IntPtr context, MulticastDelegate connectionLost, MulticastDelegate messageArrived, MulticastDelegate messageDelivered); These are my delegates
private delegate int ConnectionLostDelegate(IntPtr context, [MarshalAs(UnmanagedType.LPStr)] String cause); private delegate int MessageArrivedDelegate(IntPtr context, [MarshalAs(UnmanagedType.LPStr)] String title, Int32 titleLength, MessageObject message); private delegate int MessageDeliveredDelegate(IntPtr context, int deliveryToken); This is how I call the method
ConnectionLostDelegate conLost = new ConnectionLostDelegate(ConnectionLost); MessageArrivedDelegate mesArr = new MessageArrivedDelegate(MessageArrived); MessageDeliveredDelegate mesDel = new MessageDeliveredDelegate(MessageDelivered); result = setCallbacks(client, IntPtr.Zero, conLost, mesArr, mesDel); Here's the struct that is used by one of the callbacks
[StructLayout(LayoutKind.Sequential)] public class MessageObject { [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.U1)] public byte[] struct_id; Int32 struct_version; Int32 payloadlen; IntPtr payload; Int32 qos; Int32 retained; Int32 dup; Int32 msgid; public MessageObject() { struct_id = Encoding.ASCII.GetBytes("WXYZ"); struct_version = 0; payload = IntPtr.Zero; } } C Headers for callback functions as follows..
typedef int messageArrived(void* context, char* title, int titleLen, MessageObject* message); typedef void deliveryComplete(void* context, int token); typedef void connectionLost(void* context, char* cause);