C#调用非托管DLL中的API: pImageMem是用来存放图象数据的缓冲区 字节数组(长*宽*3) 托管数组向非托管代码封送:
LONG APIENTRY devwdm_GetImageBuffer(BYTE *pImageMem);
函数功能: 采集一帧RGB24图像到内存
pImageMem: 图像缓冲区指针
C#调用:
[DllImport("devwdm.dll")]
public static extern int devwdm_GetImageBuffer(IntPtr pImageMem);
于是报错:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
求助于大家,根据大家的意见,把API中的 BYTE* 转换到C#中,分别用 byte[] 、IntPtr 、ref byte[]、 ...甚至用unsafe了,可是还是报错,有人说内存不够大,于是我非配了很大的内存,扔报错...
万般无奈,去C++的示例程序中看,示例程序中调用该函数没有任何问题。
lpsz是文件名(用于保存图象) 字符数组(Unicode/ANSI)
devwdm_GetImageBuffer(pImageMem); 对字节数组赋值
CT_SaveBmp(lpsz,pImageMem,m_strWideth,m_strHeight,0);以BMP格式保存
CT_SaveJpeg(lpsz,pImageMem,m_strWideth,m_strHeight,0);以JPG格式保存
以C#重写上述功能,要注意的几点:
1,获取正确的m_strWideth和m_strHeight ,据此申请内存块:
IntPtr ptrImage = Marshal.AllocHGlobal(m_strWideth*m_strHeight*3);
2,构建文件名,szFile是用户输入的字符串?
string filename = "XXX";
IntPtr ptrFileName = Marshal.AllocHGlobal(filename.Length+1);
Marshal.Copy(s.ToCharArray(), 0, ptrFileName, s.Length);
3,获取图像数据:
devwdm_GetImageBuffer(ptrImage);
4,保存BMP
CT_SaveBmp(ptrFileName,ptrImage,m_strWideth,m_strHeight,0);
试试这样:
如果有byte[] data字节数组,如下调用:
devwdm_GetImageBuffer([In, MarshalAs( UnmanagedType.LPArray)] data);
或者手工转换成非托管数组:
IntPtr ptr = Marshal.AllocHGlobal(data.Length);//申请非托管内存块(与data大小一样)
Marshal.Copy(data,0,ptr,data.Length);//将托管数据复制到非托管数据
devwdm_GetImageBuffer(ptr);//直接以非托管内存块地址为参数
Marshal.FreeHGlobal(ptr);//处理完后记得释放内存
发生错误的原因是devwdm_GetImageBuffer的参数的指针没有正确指到数据内存块,当指向受保护的系统内存块并且发生读写时,就会提示上述错误,与内存大小一点关系没有
byte[] UUID2 = new byte[37];
UUID2 = System.Text.Encoding.ASCII.GetBytes(Request["uid"].Trim());
char& 和 int& ,&是取地址,在c#中byte型的数组就是表示地址的,所以,对应的类型就是byte,如果是指定长度的char的话,要用byte[] ,一定要指定长度,只可大不可小。具体咨询本站站长。