I am trying to Marshall c call backs that are in a struct. I am pretty sure I have everything correct, but when using my C# example I don't get events, when using c++ I do get events.
Here is the C#开发者_如何学C
class Program
{
[DllImport("Some.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int SetCallbacks(Callbacks callBack);
static Callbacks Callback = new Callbacks { DataArrived = DataArrived, SendFailure = SendFailure };
static void Main(string[] args)
{
SetCallbacks(Callback);
Console.ReadLine();
}
static void DataArrived(uint id, IntPtr data)
{
}
static void SendFailure(uint id, uint id2, IntPtr data)
{
}
}
[StructLayout(LayoutKind.Sequential)]
public struct Callbacks
{
public DataArrived DataArrived;
public SendFailure SendFailure;
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DataArrived(uint id, IntPtr data);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SendFailure(uint id, uint id2, IntPtr ulpData);
This is from the C header file.
struct callBacks
{
void (*dataArriveNotif) (unsigned int, void*);
void (*sendFailureNotif) (unsigned int, unsigned int, void*);
}
int SetCallbacks(callBacks callBacks);
Here is the working c++.
struct callBacks;
callbacks.dataArriveNotif = &dataArriveNotif;
callbacks.sendFailureNotif = &sendFailureNotif;
SetCallbacks(callBacks);
Everything dealing with the delegate was actually correct. I simplified the senario a little bit in the example.
public static extern int SetCallbacks(Callbacks callBack);
was actually
public static extern int SetCallbacks(String[] array, Callbacks callBack);
The string array had lots of trailing 0's at the end. Which made the callback struct all nulls. I gave up trying to marshal the string[] the correct way and just made it a Intptr and everything started working.
so very similar to this question asked yesterday...
PInvoke C#: Function takes pointer to function as argument
精彩评论