10

在我的 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 可能与此有关?

有任何想法吗?

谢谢!

4

1 回答 1

13

我设法找到了问题。这是 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

于 2009-04-28T18:16:33.607 回答