在我的C ++ DLL中的一个函数中,我将一个std :: string返回给我的c#应用程序。它几乎看起来像这样:
std::string g_DllName = "MyDLL";
extern "C" THUNDER_API const char* __stdcall GetDLLName()
{
return g_DllName.c_str();
}
但是当我的C#代码调用此函数时,我在输出窗口中收到此消息:
Invalid Address specified to RtlFreeHeap( 00150000, 0012D8D8 )
c#中的函数声明如下所示:
[DllImport("MyDll", EntryPoint = "GetDLLName")]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string GetDLLName();
根据我在网上找到的内容,有时会在删除时使用哪个版本的新版本(调试版或发布版等)之间出现不一致的消息。但我不确定这是不是我的情况。所以我不确定究竟是什么导致了它。也许MashallAs可能与它有关?
有什么想法吗?
谢谢!
答案 0 :(得分:12)
我设法找到了这个问题。这就是C#定义的完成方式。根据我的理解,将MarshallAs(UnmanagedType.LPStr)与字符串返回类型结合使用,使得它在完成后将尝试释放字符串。但是因为字符串来自C ++ DLL,并且很可能是完全不同的内存管理器,所以它失败了。即使它没有失败,我也不希望它被释放。
我找到的解决方案是将C#声明更改为此(C ++代码未更改):
[DllImport("MyDll", EntryPoint = "GetDLLName")]
public static extern IntPtr GetDLLName();
所以这使得它只返回一个指向字符串数据的指针。然后将其更改为字符串,将其传递给Marshal.PtrToStringAnsi()
return Marshal.PtrToStringAnsi(GetDLLName());
这包含在另一个清洁功能中。
我从这个页面找到了解决方案: http://discuss.fogcreek.com/dotnetquestions/default.asp?cmd=show&ixPost=1108