C# 尝试读取或写入受保护的内存。这通常指示其他内存已损坏
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 尝试读取或写入受保护的内存。这通常指示其他内存已损坏相关的知识,希望对你有一定的参考价值。
System.AccessViolationException尝试读取或写入受保护的内存。这通常指示其他内存已损坏。几经周折,觅得答案,原来是要指定
调用方式,如下就OK了:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public
delegate
void
CallbackFunc1(IntPtr
hWnd,
IntPtr
pArg);
而系统默认方式为
CallingConvention.StdCall。
程序终于不报错了,但是又出现结果不对了
定义成如下时,strName在方法中的值,只有一个字符,
public
delegate
void
CallbackFunc1(StringBuilder
strName,
IntPtr
pArg);
后来改为:
public
delegate
void
CallbackFunc1([MarshalAs(UnmanagedType.LPWStr)]
StringBuilder
strName,
IntPtr
pArg);
OK了,strName带出来的值完整了,参数类型定义成
string
或者
StringBuilder
都无所谓
还可以用
IntPtr
,或者
char*
都行(用char*
得加
unsafe)
char*
类型的,得到值后,可循环至'\0'得到整个字符串
IntPtr
类型的,可以用Marshal.Copy出来,如:
Marshal.Copy(IntPtr_source,
toBytes,
0,
1024);
如果报
“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”
异常,
还有可能是因为C++和C#的参数类型对应问题,
如:
bool
__declspec(dllimport)
getImage(unsigned
char**
ppImage,
int&
nWidth,
int&
nHeight);
对应成
[DllImport("test.dll")]
public
static
extern
bool
getImage(IntPtr
ppImage,
ref
int
nWidth,
ref
int
nHeight);时,
则该方法在调用前,要对传入的ppImage分配空间,如下
IntPtr
pImage
=
Marshal.AllocHGlobal(iWidth
*
iHeight);
这种方法不推荐,因为是带出结果来,一般这种指针不确定需要分配多大空间的。
正确的要对应成下面这样:
[DllImport("test.dll")]
public
static
extern
bool
getImage(ref
IntPtr
ppImage,
ref
int
nWidth,
ref
int
nHeight);
调用时只要定义就行了:
IntPtr
pImage
=
new
IntPtr();
int
refWidth
=
0,
refHeight
=
0;
getImage(ref
pImage,
ref
refWidth,
ref
refHeight);
总结,凡是双针指类型参数,可以用
ref
IntPtr
而对于
int*,
int&,
则都可用
ref
int
对应 参考技术A 1、delphi默认的调用顺序是
cdecl,不知道在c#中那样是不是这种调用顺序
2、PChar很可能需要外部分配好的内存。
3、你用delphi或vc也写个调用的例子试试看
以上是关于C# 尝试读取或写入受保护的内存。这通常指示其他内存已损坏的主要内容,如果未能解决你的问题,请参考以下文章