尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

sc88zy 2010-12-16 09:18:42
C#调用非托管DLL中的API:

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++的示例程序中看,示例程序中调用该函数没有任何问题。

谁能帮助我一下啊,感谢万分啊
...全文
240 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
sc88zy 2010-12-18
  • 打赏
  • 举报
回复
回复7楼大哥:

现在的问题是调用devwdm_GetImageBuffer(ptrImage)这个函数的时候,出现如题所示的错误...
一直以为是传递参数出错,可是试了很多,都是报这个错误。
sc88zy 2010-12-18
  • 打赏
  • 举报
回复
回复7楼大哥:

现在的问题是调用devwdm_GetImageBuffer(ptrImage)这个函数的时候,出现如题所示的错误...
一直以为是传递参数出错,可是试了很多,都是报这个错误。
acer3680 2010-12-18
  • 打赏
  • 举报
回复
出售 oa系统源码,系统使用asp.net+sql2005 开发,并承接c#程序编写,有意请联系QQ:114805001
  • 打赏
  • 举报
回复
pImageMem是用来存放图象数据的缓冲区 字节数组(长*宽*3)
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);

试试
可以贴出你的调用代码来看看


sc88zy 2010-12-18
  • 打赏
  • 举报
回复
感谢大家的帮助,不过还是没解决,DLL是厂家封装好的,给的示例程序中也是调用封装好的DLL。这是C++示例程序中对该函数的调用:

LPTSTR lpsz = new TCHAR[szFile.GetLength()+1];
_tcscpy(lpsz,szFile);

BYTE * pImageMem = (BYTE*)malloc(m_strWideth* m_strHeight * 3);

devwdm_GetImageBuffer(pImageMem);

if(nbBmp == true)
CT_SaveBmp(lpsz,pImageMem,m_strWideth,m_strHeight,0);
else
CT_SaveJpeg(lpsz,pImageMem,m_strWideth,m_strHeight,0);

free(pImageMem);
delete lpsz;
sc88zy 2010-12-18
  • 打赏
  • 举报
回复
如果不是参数传递错误,那么Marshal.AllocHGlobal()方法申请的内存块怎么会报出:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。这个错误呢?
  • 打赏
  • 举报
回复
托管数组向非托管代码封送:

试试这样:
如果有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的参数的指针没有正确指到数据内存块,当指向受保护的系统内存块并且发生读写时,就会提示上述错误,与内存大小一点关系没有
宝_爸 2010-12-18
  • 打赏
  • 举报
回复

感觉这种方式应该是对的。

[DllImport("devwdm.dll")]
public static extern int devwdm_GetImageBuffer(byte[] pImageMem);
宝_爸 2010-12-18
  • 打赏
  • 举报
回复
有devwdm_GetImageBuffer的souce code和PDB文件吗。如果有可以试着跟踪进去看看
zhl8419 2010-12-17
  • 打赏
  • 举报
回复
这问题我也碰到了 同样求解

111,093

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

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