从 c# 项目 System.AccessViolationException 调用 c++ char*
Posted
技术标签:
【中文标题】从 c# 项目 System.AccessViolationException 调用 c++ char*【英文标题】:calling c++ char* from c# project System.AccessViolationException 【发布时间】:2018-11-05 14:49:35 【问题描述】:我试图从一个 c# 项目中调用一个 c++ 库方法,但没有取得多大成功。我总是遇到同样的错误。
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
c++ 方法签名是这样的
int __stdcall getErrorMessage(int errorId, char *&errorMessage);
到目前为止,我已经尝试了所有组合,但似乎没有任何效果。
[DllImportAttribute("Lib.dll", EntryPoint = "getErrorMessage",
CallingConvention = CallingConvention.StdCall)]
public static extern int getErrorMessage(int errorId, ref StringBuilder errorMessage);
[DllImportAttribute("Lib.dll", EntryPoint = "getErrorMessage",
CallingConvention = CallingConvention.StdCall)]
public static extern int getErrorMessage(int errorId, ref IntPtr errorMessage);
[DllImportAttribute("Lib.dll", EntryPoint = "getErrorMessage",
CallingConvention = CallingConvention.StdCall)]
public static extern int getErrorMessage(int errorId, IntPtr errorMessage);
任何帮助将不胜感激。
编辑
我的称呼方式如下
var ptr = new IntPtr();
var ret = NativeMethods.getErrorMessage(number, ref ptr);
还有一个调用完成后释放内存
【问题讨论】:
请提供minimal reproducible example 那么 getErrorMessage 可能分配了一些内存并在 char*& 参数中返回指向它的指针?为了正确清理,您需要知道该内存是如何分配的。如果它不是互操作层支持的分配器之一(例如 CoTaskMemAlloc),我担心你不走运。当然,您始终可以使用 C++/CLI 编写包装器库。 还有另一种方法可以释放此调用分配的内存。我调用它的方式是 var ptr = new IntPtr(); var ret = NativeMethods.getErrorMessage(number, ref ptr); 你看到了吗? ***.com/questions/14816970/… ref IntPtr 是正确的,你是否传递了一个有效的数字是无法猜测的。假设您应该只在另一个函数指示失败时调用它,这可能是明智的。将一个小型 repro 项目发送给 C++ 代码的作者,以便他进行调试。 【参考方案1】:获得IntPtr
后,您应该使用PtrToStringAuto
或PtrToStringAnsi
将其转换为string
【讨论】:
【参考方案2】:它终于起作用了,正如 Hans Passant 所说,当我们尝试使用任意错误代码查询该方法时,问题就发生了。
工作代码。
var ptr = new IntPtr(); var ret = NativeMethods.getErrorMessage(code, ref ptr); if (ptr != IntPtr.Zero) message = Marshal.PtrToStringAnsi(ptr); NativeMethods.freePointer(ref ptr);
感谢您的帮助。
【讨论】:
以上是关于从 c# 项目 System.AccessViolationException 调用 c++ char*的主要内容,如果未能解决你的问题,请参考以下文章
使用 Powershell 或 C# 从 TFS 项目中删除用户
从 c# 项目 System.AccessViolationException 调用 c++ char*
如何将 .exe 从 C++ 项目复制到 C# 项目的输出目录?