You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#向原生函数传递null委托的处理机制及结果问询

问题背景

假设有一个名为mylib.so的C语言库,暴露以下接口:

typedef void (*EventCallback)(int);

// Windows平台下会额外定义对应的declspec宏
void AddEventHandler(EventCallback ec);

在C#中,我们按如下方式调用mylib.so:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void EventCallback(int type);

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void AddEventHandlerFn(EventCallback? ec);

// 在后续代码中...

IntPtr libHandle = NativeLibrary.Load("mylib.so");
var addEventHandler = Marshal.GetDelegateForFunctionPointer<AddEventHandlerFn>(
  NativeLibrary.GetExport(libHandle, "AddEventHandler")
);

addEventHandler(null);

问题:当在C#中调用addEventHandler(null)时,C语言函数中是否会接收到(EventCallback)0?若否,实际会发生什么?

答案

是的,C语言函数会接收到(EventCallback)0(即空函数指针)。

具体原因:

  • 在C#与非托管代码的封送逻辑中,当传递null作为委托类型参数时,CLR会直接将其转换为对应非托管环境的空指针。
  • 这里的EventCallback?是可空委托类型,传递null时,封送器会严格按照约定将其映射为C语言里的空函数指针(EventCallback)0。
  • 只要调用约定(此处为Cdecl)与非托管库的约定匹配,这种空值封送是完全符合预期的,不会产生额外异常——除非C库本身对空指针有非法操作,但这属于库自身的逻辑问题,和封送机制无关。

内容的提问来源于stack exchange,提问作者itzjackyscode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 04:45:43