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

C++ SDK封装后C#事件无法获取图像API数据问题求助

问题排查与修复方案

1. 回调函数参数不匹配(核心问题)

C++侧问题:

  • 定义的image_acquired_callback签名是void(uint16_t, uint16_t, int, int, const uint16_t*, bool),但在image_acquired重载方法里调用dotnet_callback(width, height, image)时,仅传递了3个参数,与签名要求的6个参数完全不符,导致回调无法正确触发。
  • 第一段C++代码里的dotnet_callback(width, height, image, );存在语法错误(末尾多余逗号)。

C#侧问题:

  • 委托ImageAcquiredCallback的签名是void(int width, int height, ushort* image),与C定义的6参数签名不匹配,即使C调用逻辑正确,C#也无法正确接收参数。
  • OnImageAcquired方法包含6个参数,但实际绑定的事件委托仅定义了3个参数,参数数量不对应,逻辑上无法衔接。

2. 事件绑定时机错误

你先调用device.StartAcquisition()启动采集,之后才绑定device.ImageAcquired += Device_ImageAcquired,这会导致采集启动后产生的图像事件无法被新绑定的处理函数捕获。正确顺序应为先绑定事件,再启动采集:

device.ImageAcquired += Device_ImageAcquired;
device.connect();
device.StartAcquisition();

3. 图像指针生命周期风险

C++回调中的const uint16_t* image是临时指针,回调结束后SDK可能会释放这块内存。C#中直接使用ushort* image访问,可能出现内存访问错误或数据失效。需在回调内立即复制图像数据:

unsafe void Device_ImageAcquired(int width, int height, ushort* image)
{
    // 复制数据到托管数组
    ushort[] imageData = new ushort[width * height];
    Marshal.Copy((IntPtr)image, imageData, 0, width * height);
    // 后续EmguCV处理使用imageData
}

4. 回调触发逻辑缺失

从代码来看,OnImageAcquired方法应负责触发ImageAcquired事件,但未看到C回调如何映射到这个C#方法的逻辑,需确认封装层是否正确完成了C到C#的回调转接。

修复后的关键代码示例

C++侧修正回调调用:

virtual void image_acquired(
    int width,
    int height,
    const uint16_t* image) override {
    // 根据实际SDK逻辑补充缺失的参数值
    dotnet_callback(0, 0, width, height, image, false);
}

C#侧修正委托与事件逻辑:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
unsafe public delegate void ImageAcquiredCallback(ushort bank, ushort frame, int width, int height, ushort* image, bool moreAvailable);

public event ImageAcquiredCallback ImageAcquired;
private unsafe void OnImageAcquired(ushort bank, ushort frame, int width, int height, ushort* image, bool moreAvailable)
{
    ImageAcquired?.Invoke(bank, frame, width, height, image, moreAvailable);
}

// 对应修正事件处理函数参数
unsafe void Device_ImageAcquired(ushort bank, ushort frame, int width, int height, ushort* image, bool moreAvailable)
{
    ushort[] imageData = new ushort[width * height];
    Marshal.Copy((IntPtr)image, imageData, 0, width * height);
    // 后续EmguCV处理逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:17:24