【问题标题】:calling c++ char* from c# project System.AccessViolationException从 c# 项目 System.AccessViolationException 调用 c++ char*
【发布时间】: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++ 代码的作者,以便他进行调试。

标签: c# c++ interop


【解决方案1】:

获得IntPtr 后,您应该使用PtrToStringAutoPtrToStringAnsi 将其转换为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);
            }
    

    感谢您的帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      相关资源
      最近更新 更多