Interop C#/ C的问题:AccessViolationException
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Interop C#/ C的问题:AccessViolationException,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含1578字,纯文字阅读大概需要3分钟。
内容图文
![Interop C#/ C的问题:AccessViolationException](/upload/InfoBanner/zyjiaocheng/672/7c2833b036c245ef91eb1ef73770636e.jpg)
感谢您的帮助.
我在C中有这个琐碎的功能:
__declspec(dllexport) Point* createPoint (int x, int y) {
Point *p;
p = (Point*) malloc(sizeof(Point));
p->x = x;
p->y=y;
return p;
}
Point是具有两个int字段x和y的非常简单的结构.
我想从C#调用此函数.
我使用以下代码:
[DllImport("simpleC.dll", EntryPoint = "createPoint", CallingConvention = CallingConvention.Cdecl, SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern Point createPoint(int x, int y);
Point p = Wrapper.createPoint(1, 2);
但是在运行时,我有一个AccessViolationException.详细查看异常,我发现Marshal.CoTaskMemFree(IntPtr)方法引发了异常.
似乎该方法无法释放C malloc分配的内存.
我究竟做错了什么?
真的感谢.
解决方法:
CoTaskMemFree无法用于释放由malloc分配的内存(因为它们使用不同的分配器).根据MSDN,“运行时始终使用CoTaskMemFree方法来释放内存.如果正在使用的内存未使用CoTaskMemAlloc方法分配,则必须使用IntPtr并使用适当的方法手动释放内存.”
另外,Adam Nathan notes指出“仅在一种特定情况下支持UnmanagedType.LPStruct:将System.Guid值类型作为具有额外间接级别的非托管GUID….您可能应该远离UnmanagedType.LPStruct.”
有两种可能的解决方案:
>将方法的返回类型声明为IntPtr,并使用Marshal.ReadInt32读取结构的字段,或使用Marshal.PtrToStructure将数据复制到托管结构,或使用不安全的代码将IntPtr值转换为Point *. C库将需要公开一个destroyPoint(Point *)方法来释放内存.
>将C方法签名更改为void getPoint(int x,int y,Point *).这使C#可以分配结构,而C方法只需填写数据值. (大多数Win32 API都是通过这种方式定义的).
最后一点:除非您的方法使用SetLastError Win32 API,否则您无需在P / Invoke属性上指定SetLastError = true.
内容总结
以上是互联网集市为您收集整理的Interop C#/ C的问题:AccessViolationException全部内容,希望文章能够帮你解决Interop C#/ C的问题:AccessViolationException所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。