C#调用C dll一些走过坑的笔记

笔记1:

c dll的call convention 是cdecl ,弄了一个CallBack,供外部调用。

C#方面 在debug模式下,委托不加UnmanagedFunctionPointer是正常的,在release模式下不加UnmanagedFunctionPointer不行,加上UnmanagedFunctionPointer才正常。

错误的写法:

internal delegate void Internal_Can_ReceiveCallBack_t(IntPtr device, CAN_RxPacket_t rx);
internal delegate void Internal_Can_TxErrorCallBack_t(IntPtr device, CAN_TxPacket_t tx);
internal delegate void Internal_Can_ControlUnitStatusUpdateCallBack_t(IntPtr device, CAN_ControlUnitStatus_t status);

正确的写法:

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    internal delegate void Internal_Can_ReceiveCallBack_t(IntPtr device, CAN_RxPacket_t rx);
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    internal delegate void Internal_Can_TxErrorCallBack_t(IntPtr device, CAN_TxPacket_t tx);
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    internal delegate void Internal_Can_ControlUnitStatusUpdateCallBack_t(IntPtr device, CAN_ControlUnitStatus_t status);

总结:

以后调用一切的C/C++ dll  任何函数 任何委托 全部显式写出  CallingConvention

笔记2:

有如下函数:

[DllImport("my.dll",CallingConvention= CallingConvention.Cdecl,EntryPoint = "setCallBack")]
private static extern void setCallBack(myCallBack_t callback);

相当于C#写CallBack供 C dll调用, 那么在C#方面一定要搞一个委托的实例字段 将C#方法付给这个实例,再将实例传给C dll

错误写法:

C#:
public void foo()
{
......
}

setCallBack(foo);

正确的写法:

public void foo()
{
......
}
private myCallBack_t internalMyCallBack;

internalMyCallBack=foo;
setCallBack(internalMyCallBack);

原因参照MDA, 百度搜一下callbackOnCollectedDelegate ,也很简单,搞一个字段,将函数赋给这个字段的话,字段在相当于一直在引用这个委托的实例,GC就不会回收这个委托的实例,如果字段所在的类对象在程序运行期间 一直存在,那么 GC就不会回收此字段以及此字段所在的类对象。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值