调用非托管回调后程序会爆炸 [英] Program blows up after unmanaged callback is called

查看:475
本文介绍了调用非托管回调后程序会爆炸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要从我的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆