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
相关产品推荐
相关产品推荐

