我正在尝试 Marshall c 结构中的回调。我很确定我的一切都是正确的,但是当使用我的 C# 示例时,我没有得到事件,而当使用 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);
这是来自 C 头文件。
struct callBacks
{
void (*dataArriveNotif) (unsigned int, void*);
void (*sendFailureNotif) (unsigned int, unsigned int, void*);
}
int SetCallbacks(callBacks callBacks);
这是工作的 c++。
struct callBacks;
callbacks.dataArriveNotif = &dataArriveNotif;
callbacks.sendFailureNotif = &sendFailureNotif;
SetCallbacks(callBacks);
最佳答案
与代表打交道的一切实际上都是正确的。我在示例中稍微简化了 senario。
public static extern int SetCallbacks(Callbacks callBack);
实际上是
public static extern int SetCallbacks(String[] array, Callbacks callBack);
字符串数组末尾有很多尾随 0。这使得回调结构全部为空。我放弃了尝试以正确的方式编码 string[],只是将其设为 Intptr,然后一切都开始工作了。
关于C# 编码回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5250478/