C++/CLI 调用 C DLL ,错误:此Bug常见来源包括用户对 COM-interope 或 Pinvoke的封送处理,这些错误可能会损坏堆栈

qingfy2007 2013-05-29 09:46:35
背景介绍:

现有 C 和 C ++ 的混合代码,我要用 C++/CLI 去调用它,考虑到语言的差异,所以要将前者封装成 DLL。

C 函数原型:

int fb_data_send_Me(omap_usb_handle *usb, const void *data, unsigned size, unsigned count);

该函数的作用是往指定的 usb 对象中写入 data ,data 的长度是 size,count 是写的次数;

其中:fb_data_send_Me 第一句代码是这样的:

unsigned char* ptr = (unsigned char*) data; // 可见传递的是 unsigned char 类型数组;
...全文
6703 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lqylevin 2013-10-18
  • 打赏
  • 举报
回复
你好 问下这个问题解决了么 我也是报的同样的错误,在C#中调用了C++的代码,导致堆栈出错。但是对封装、封送知识还不大了解,嫩那个不能赐教下。多谢多谢
真相重于对错 2013-05-30
  • 打赏
  • 举报
回复
没仔细看,你使用c++/cli啊,他可以直接调用非托管dll,而不要像C#那样还要自己再封装一下
qingfy2007 2013-05-29
  • 打赏
  • 举报
回复
之后有一个类 usbdriver 继承了该类,其具体如下: class API UsbDriver : public ComDriver { public: UsbDriver(U16 sid = 0); ~UsbDriver(); S8 open(U8 port, U32 baudRate, U8 parity, U8 stopBits, U8 data); S8 close(void); S8 reset(void); S8 configure(U32 baudRate, U8 parity, U8 stopBits, U8 data); S32 write(U8 *buffer, U32 size); S32 read(U8 *buffer, U32 size, U32 timeout); void registerCallback(T_COM_DRV_CALL_BACK callback); void unregisterCallback(); void registerConnectionLostCallback(T_COM_DRV_CONNECTION_LOST_CALL_BACK callback); U16 sid() { return sessionId; } int getDrvErr() { return driverErr; } // // 手动添加测试; // int add( int x,int y ); private: U8 portNum; U16 sessionId, threadId; bool isOpen; bool isClosing; bool rxComplete; U8 *readFifo; U32 readFifoPtr; U32 readFifoBytesAvailable; HANDLE usbDevice; HANDLE listener; HANDLE readyEvent; HANDLE shutdownEvent; char driverName[50]; int driverErr; unsigned char bulkInPipe; unsigned char bulkOutPipe; WINUSB_INTERFACE_HANDLE winUsbHandle; T_COM_DRV_CALL_BACK rxCallback; T_COM_DRV_CONNECTION_LOST_CALL_BACK connectionLostCallback; HANDLE getDeviceHandle(U8 port); void getDriverName(char deviceKeyName[]); void getDeviceKeyName(char usbPath[], char deviceKeyName[]); S32 readHw(U8 *buffer, U32 size, U32 timeout); // to use for WinUSB bool initializeDevice(); friend unsigned int __stdcall usbListener(void *drvObj); }; 我在进行封送的时候,在C++/CLI 中重构了 usbdriver 的所有变量,在程序跟踪时发现所有的变量都被赋值了,这个可能没错吧。 还是感谢以上的回答。 我明天尝试一下奉送 comdriver 这个抽象类试试
qingfy2007 2013-05-29
  • 打赏
  • 举报
回复
第一个参数是个抽象类,其源代码是这样子的: class ComDriver { public: virtual ~ComDriver() { }; virtual S8 open(U8 port, U32 baudRate, U8 parity, U8 stopBits, U8 data) = 0; virtual S8 close(void) = 0; virtual S8 reset(void) = 0; virtual S8 configure(U32 baudRate, U8 parity, U8 stopBits, U8 data) = 0; virtual S32 write(U8 *buffer, U32 size) = 0; virtual S32 read(U8 *buffer, U32 size, U32 timeout) = 0; virtual void registerCallback(T_COM_DRV_CALL_BACK callback) = 0; virtual void unregisterCallback() = 0; virtual void registerConnectionLostCallback(T_COM_DRV_CONNECTION_LOST_CALL_BACK callback) = 0; virtual U16 sid() = 0; virtual int getDrvErr() = 0; protected: U8 debugLevel; virtual U8 initDebugLevel(); virtual void debugPrint(U8 level, const char *format, ...); };
qingfy2007 2013-05-29
  • 打赏
  • 举报
回复
对于方式二的引用: writeTotal = fb_data_send_Me( drv_usb,buffer, (unsigned int)buffer->Length, (unsigned int)0 )); 其中:buffer 为已经填充 Ok 的unsigned char 星字节数组。 编译还是报告相同的错误。
真相重于对错 2013-05-29
  • 打赏
  • 举报
回复
第一个参数可能就错了 omap_usb_handle 类型是托管的还是非托管的,如果是非托管的不能用^
qingfy2007 2013-05-29
  • 打赏
  • 举报
回复
程序报告错误,截图如下:
qingfy2007 2013-05-29
  • 打赏
  • 举报
回复
对于声明一的调用方式: int total = 1; int size = 0; int writeTotal = 0; // 存储实际写入的数据量; array< System::IntPtr >^ ptBuffer = gcnew array< System::IntPtr >( total ); size = System::Runtime::InteropServices::Marshal::SizeOf( buffer[0] ) * buffer->Length; // 获取数组大小,buffer 为已经被填充的,即将传递下去的字节数组; ptBuffer[0] = System::Runtime::InteropServices::Marshal::AllocHGlobal( size ); // 分配非托管内存,到时候要手动释放; System::Runtime::InteropServices::Marshal::Copy( buffer,0,(System::IntPtr)ptBuffer[0],buffer->Length ); // 复制托管数组到非托管内存; // // 使用复制内存的方法,并且使用 drv_usb 对象,NG; // writeTotal = fb_data_send_Me( drv_usb, ( System::IntPtr )ptBuffer[0], (unsigned int)buffer->Length, (unsigned int)0 );
qingfy2007 2013-05-29
  • 打赏
  • 举报
回复
我的处理方法: 我尝试了三种方法在 C++/CLI 中对 fb_data_send_Me进行声明: 声明式样一: int fb_data_send_Me( UsbDriver^ usb, System::IntPtr data, unsigned int size, unsigned int count); 声明样式二: int fb_data_send_Me( UsbDriver^ usb, [MarshalAs(UnmanagedType::LPArray,SizeParamIndex = 1)] array< byte >^ data, unsigned int s ize, unsigned int count ); 声明式样三: int fb_data_send_Me( UsbDriver^ usb, array<byte>^ data, unsigned int size, unsigned int count);

1,978

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 其他语言讨论
社区管理员
  • 其他语言社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧