关于C#调用C++回调函数传指针地址参数问题。。。

时间:2021-07-25 20:52:16
关于C#调用C++回调函数传指针地址参数问题。。。

最近在项目中需要使用C++写地层的SOCKET通讯,作成通讯的DLL库。功能是:接收客户端传入的图形文件数据,然后采用回调函数将图形指针传给外部的C#程序。。。
出现了,指针异常,以及读出指针数据后乱码,以及格式不正确等错误。。请大家帮忙分析下。。

C++的回调函数的参数:
。。。。(char*pUID,char*pImageAddr,unsign int mImageSize);
pUID,为图形的唯一ID,c++传出
pImageAddr,为图形的指针启始地址,c#传入地址
mImageSize, 为图形的大小,c++传出

C#的委托参数定义为:
。。。。(string pUID,StringBuilder pImageAddr,unsign int mImageSize);
其中第二个图形地址参数,分别采用了IntPtr,ref byte,等来作为传入参数,均不正确。。。
请大家帮助下,据说要采用unsafe,以及fixed固定要传入的指针??
还有,据说在c++和c#里面二进制流不同???(c++中的图形采用byte流保存)
。。。
万分感激,谢谢。。。

10 个解决方案

#1


char*pImageAddr是指向图形数据的内存区域么?
那么用byte[]试试~

#2


up

jf

#3


编程爱好者请加群88718955,大家一起探讨,学习

#4


C#中的byte[]对应C++的字节流。

#5


谢谢,我使用INTPTR将指针地址读出来了,和C++里面一样的地址,然后使用Mashal读取长度的字节后,再用这个字节流反系列化为Image对象是老错。。。
也进行了转换的啊???
使用BYTE[]再看看。。。

#6


C++的图片数据不可能是.NET的Image对象……肯定不能把这些数据直接反序列化吧……
不知道是不是包含bmp的信息头。否则的话可以新建一个MemoryStream并用你的byte[]初始化流,然后用Bitmap.FromStream来读取。试一下吧。不知道C++代码返回的具体数据格式,不好确定怎么办。

#7


楼上的说的好,
我尝试看看。。。
否则的话可以新建一个MemoryStream并用你的byte[]初始化流???
是不是
需要把这个byte[]流处理
下?
将头之类的信息去掉???

#8


有头最好啊,干啥去掉,有头的话估计就是标准bmp了,直接用这byte[]创建Stream然后用Bitmap.FromStream来读取,应该就成了

#9


to wjq:
    thanks!
一切OK,结贴拉。。。
总结下:
1。采用IntPtr作为参数传递,不需要采用unsafe 模式。。。
2。采用新建一个MemoryStream并用你的byte[]初始化流,然后用Bitmap.FromStream来读取

#10


没弄过,请教楼主是怎么传递IntPtr的?
dll里面的参数是IntPtr类型,在C#里面传递一个new的IntPtr类型给它,会报错“尝试读取或写入受保护的内存。这通常指示其他内存已损坏” 
dll里面:CaptureFromUSB(uint enHandle, IntPtr pBuffer, int srcWidth, int srcHeight);
CallBackAction(IntPtr pRGBBuf, int imgWidth, int imgHeight)里面调用CaptureFromUSB函数,
Form里面调用:
IntPtr pnt = new IntPtr(2121);//不知道对不对
CallBackAction(pnt, 320, 240);//这里调用过去就报错

想读取数据流,然后转换为图片,谢谢

#1


char*pImageAddr是指向图形数据的内存区域么?
那么用byte[]试试~

#2


up

jf

#3


编程爱好者请加群88718955,大家一起探讨,学习

#4


C#中的byte[]对应C++的字节流。

#5


谢谢,我使用INTPTR将指针地址读出来了,和C++里面一样的地址,然后使用Mashal读取长度的字节后,再用这个字节流反系列化为Image对象是老错。。。
也进行了转换的啊???
使用BYTE[]再看看。。。

#6


C++的图片数据不可能是.NET的Image对象……肯定不能把这些数据直接反序列化吧……
不知道是不是包含bmp的信息头。否则的话可以新建一个MemoryStream并用你的byte[]初始化流,然后用Bitmap.FromStream来读取。试一下吧。不知道C++代码返回的具体数据格式,不好确定怎么办。

#7


楼上的说的好,
我尝试看看。。。
否则的话可以新建一个MemoryStream并用你的byte[]初始化流???
是不是
需要把这个byte[]流处理
下?
将头之类的信息去掉???

#8


有头最好啊,干啥去掉,有头的话估计就是标准bmp了,直接用这byte[]创建Stream然后用Bitmap.FromStream来读取,应该就成了

#9


to wjq:
    thanks!
一切OK,结贴拉。。。
总结下:
1。采用IntPtr作为参数传递,不需要采用unsafe 模式。。。
2。采用新建一个MemoryStream并用你的byte[]初始化流,然后用Bitmap.FromStream来读取

#10


没弄过,请教楼主是怎么传递IntPtr的?
dll里面的参数是IntPtr类型,在C#里面传递一个new的IntPtr类型给它,会报错“尝试读取或写入受保护的内存。这通常指示其他内存已损坏” 
dll里面:CaptureFromUSB(uint enHandle, IntPtr pBuffer, int srcWidth, int srcHeight);
CallBackAction(IntPtr pRGBBuf, int imgWidth, int imgHeight)里面调用CaptureFromUSB函数,
Form里面调用:
IntPtr pnt = new IntPtr(2121);//不知道对不对
CallBackAction(pnt, 320, 240);//这里调用过去就报错

想读取数据流,然后转换为图片,谢谢