调用非托管回调后程序会爆炸 [英] Program blows up after unmanaged callback is called
问题描述
我有一个需要从我的c#应用程序调用的c dll。
我让它与dll通信,但是我遇到了回调问题。
c看起来像这样。
I have an c dll that I need to call from my c# application.
I have it communicating with the dll, but I am having issues with callbacks.
The c looks like this.
typedef void (CDECLCALL_CONV *ConnectedCB) (DPHandle hdl);
typedef struct
{
unsigned int size; // sizeof(DPcbs)
ConnectedCB connectedCB;
.. more callbacks
} DPcbs;
BPS_DP_API unsigned long CDECLCALL_CONV DPSetCallBacks(DPHandle hdl, DPcbs *DPcbs);
我是什么尝试过:
我创建了一个包装非托管代码的接口类。
它看起来像这样
What I have tried:
I have created a interface class that wraps the unmanaged code.
It looks like this
[System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.Cdecl)]
public delegate void ConnectedCB(ref DocProcHandle hdl);
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct DPcbs
{
public uint size;
public ConnectedCB connectedCB;
... more callbacks
}
[System.Runtime.InteropServices.DllImportAttribute("DocProc.dll", EntryPoint = "DPSetCallBacks", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)]
public static extern uint DPSetCallBacks(ref DocProcHandle hdl, ref DPcbs DPcbs);
最后我的c#调用代码
Finally My c# calling code
{
...
// this code is in a static class in the constructor
// it should not be garbage collected right?
m_events = new DPcbs();
m_events.connectedCB = connected;
m_events.size = Convert.ToUInt32(Marshal.SizeOf<DPcbs>());
wrapper.DPSetCallBacks(ref m_handle, ref m_events);
...
}
private void connected(ref DocProcHandle hdl)
{
// do something here
}
应用程序停止工作 - 没有错误只是崩溃。
但它发生在调用连接方法之后,在任何事情之前否则。
如果我没有设置连接的回调,它不会崩溃。 (如果它试图调用我的任何回调,它似乎会崩溃)
我已经尝试了所有我能想到的方法以确保该方法不通过GC 。
这个类是静态的,我把方法设为静态。我有Alloc'ed方法和事件。
我有什么遗漏或做错了吗?
有关尝试什么的建议吗?
The application "stopped working" - no error just a crash.
But it happens AFTER the connected method is called, and before anything else.
If I do not set the connected callback it does not crash. (it seems to crash if it tries to call any of my callbacks)
I have tried everything i can think of to make sure the method does not go through the GC.
The class is static, I have made the method static. I have Alloc'ed both the method and the event.
Is there anything I am missing or doing wrong?
Any suggestions on what to try?
推荐答案
您无法以您尝试的方式将委托传递给非托管代码。如果你要将它作为函数指针传递给结构,你应该调用:
You can't pass the delegate to unmanaged code the way you are trying to do. If you are going to pass it as a function pointer inside a structure, you should call:
IntPtr NativeFunctionPointer = Marshal.GetFunctionPointerForDelegate(connected);
然后传递 NativeFunctionPointer
作为函数指针。
原因是托管委托不仅仅包含一个函数地址。它有许多其他.NET类的代码和数据,因此传递其地址与传递其函数入口点不同。
Then pass NativeFunctionPointer
as the function pointer.
The reason is that a managed delegate consists of more than just a function address. It has code and data like many other .NET classes, so passing its address isn't the same as passing its function entry point.
这篇关于调用非托管回调后程序会爆炸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!