如何将 C++/CLI 字符串转换为 const char*

Jim*_*m C 5 c c# c++ dll

我有一个 C++/CLI DLL,我计划用作我的 C# DLL 和本机 C++ 客户端之间的适配器。我需要在两个方向传递字符串。该适配器是用 VS2013 编译的,但需要支持用 VS2008 构建的客户端,所以我在 API 中使用了 const char*。但是即使两者都是 VS2013 构建的,我所拥有的也不起作用。

在其他地方,我找到了使用 msclr\marshal.h 的建议,所以我创建了:

using namespace msclr::interop;
System::String^ ToCliString(const char* s)
{
    System::String ^result = marshal_as<System::String^>(s);
    return result;
}    
const char* ToCppString(System::String^ s)
{
    msclr::interop::marshal_context context;
    const char* result = context.marshal_as<const char*>(s);
    return result;
}
Run Code Online (Sandbox Code Playgroud)

为了测试这些,我在我的 C++/CLI DLL 中创建了一个往返转换方法:

const char* Foo(const char *cstar)
{
    System::String^ cli = ::ToCliString(cstar);

    if (cli == "abc")
    {
        MessageBox::Show("const char* -> CLI: OK");
    }

    const char* cstar2 = ::ToCppString(cli);

    if (std::strcmp(cstar2, "abc") == 0)
    {
        MessageBox::Show("CLI -> const char*: OK");
    }
    else if (std::strcmp(cstar2, "") == 0)
    {
        MessageBox::Show("ToCppString returned empty string");
    }
    else
    {
        MessageBox::Show("ToCppString returned something else");
    }

    return cstar2;
}
Run Code Online (Sandbox Code Playgroud)

当本机 C++ 客户端调用 Foo("abc") 时,将显示第一条消息,显示“返回的其他内容”消息,并且客户端收到垃圾邮件 (îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþÞ›vÚ§)。所以看起来我的第二次转换不起作用。

更新

这是我使用的最终解决方案。

我使用 zneaks 的建议来编组到 std::string 和 PaulMcKenzie 的建议来传递调用者分配的 char* 而不是返回 const char*。谢谢你们俩。

void ToCppString(System::String^ input, char* output)
{
    std::string temp= marshal_as<std::string>(input);
    strcpy(output, temp.c_str());
}

void Foo(const char* input, char* output)
{
    System::String^ cli = ::ToCliString(input);
    ::ToCppString(cli, output);
}
Run Code Online (Sandbox Code Playgroud)

zne*_*eak 3

问题是 拥有marshal_context您获得的 char 指针,因此当您的函数返回时它会被释放

此示例创建一个上下文,用于从System::String封送至const char *变量类型。在删除上下文的行之后,转换后的数据将无效。

考虑使用marshal_as<std::string>代替,因为允许字符串比marshal_context.