【发布时间】: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);
还有一个调用完成后释放内存
【问题讨论】:
-
那么 getErrorMessage 可能分配了一些内存并在 char*& 参数中返回指向它的指针?为了正确清理,您需要知道该内存是如何分配的。如果它不是互操作层支持的分配器之一(例如 CoTaskMemAlloc),我担心你不走运。当然,您始终可以使用 C++/CLI 编写包装器库。
-
还有另一种方法可以释放此调用分配的内存。我调用它的方式是 var ptr = new IntPtr(); var ret = NativeMethods.getErrorMessage(number, ref ptr);
-
ref IntPtr 是正确的,你是否传递了一个有效的数字是无法猜测的。假设您应该只在另一个函数指示失败时调用它,这可能是明智的。将一个小型 repro 项目发送给 C++ 代码的作者,以便他进行调试。