相关疑难解决方法(0)

C#中的std :: string?

我认为问题出在我的C++函数中,但我试过了

C++中的C++函数:

bool __declspec( dllexport ) OpenA(std::string file)
{
return true;
}
Run Code Online (Sandbox Code Playgroud)

C#代码:

[DllImport("pk2.dll")]
public static extern bool OpenA(string path);

    if (OpenA(@"E:\asdasd\"))
Run Code Online (Sandbox Code Playgroud)

我得到一个例外,内存已损坏,为什么?

如果我删除了std :: string参数,它的效果很好,但是使用std :: string它不起作用.

c# c++ dll

8
推荐指数
2
解决办法
2万
查看次数

将std :: wstring的内容从C++返回到C#

我有一个非托管的C++ DLL,我用一个简单的C接口包装,所以我可以从C#上调用PInvoke.这是C包装器中的示例方法:

const wchar_t* getMyString()
{
    // Assume that someWideString is a std::wstring that will remain
    // in memory for the life of the incoming calls.
    return someWideString.c_str();
}
Run Code Online (Sandbox Code Playgroud)

这是我的C#DLLImport设置.

[DllImport( "my.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl )]
private static extern string GetMyString();
Run Code Online (Sandbox Code Playgroud)

然而,字符串没有被正确编组,通常搞砸了第一个字符,或者有时会显示出一堆中文字符.我已经记录了C端实现的输出,以确认std :: wstring是否正确形成.

我还尝试更改DLLImport以返回IntPtr并使用Marshal.PtrToStringUni使用包装方法进行转换,它具有相同的结果.

[DllImport( "my.dll", CallingConvention = CallingConvention.Cdecl )]
private static extern IntPtr GetMyString();
public string GetMyStringMarshal()
{
    return Marshal.PtrToStringUni( GetMyString() );
}
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?

用答案更新

因此,如下所述,这不是我的绑定的问题,而是我的wchar_t*的生命周期.我的书面假设是错误的,someWideString实际上是在我调用应用程序的其余部分时被复制的.因此它只存在于堆栈中,并且在我的C#代码完成编组之前就被释放了.

正确的解决方案是将指针传递给我的方法,如shf301所述,或者确保在我的C#接口有时间复制之前,我的wchar_t*引用不会被移动/重新分配/销毁.

将std :: wstring作为"const&std :: wstring"返回到我的C层意味着我对c_str()的调用将返回一个不会在我的C方法范围之外立即释放的引用.

然后调用C#代码需要使用Marshal.PtrToStringUni()将数据从引用复制到托管字符串.

c# c++ unicode interop

3
推荐指数
2
解决办法
6699
查看次数

标签 统计

c# ×2

c++ ×2

dll ×1

interop ×1

unicode ×1