简体   繁体   English

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

[英]How to convert C++/CLI string to const char*

I've got a C++/CLI DLL I plan to use as an adapter between my C# DLL and native C++ clients. 我有一个C ++ / CLI DLL,我计划用作C#DLL和本机C ++客户端之间的适配器。 I need to pass strings in both directions. 我需要在两个方向传递字符串。 The adapter is compiled with VS2013 but needs to support clients built with VS2008 so I'm using const char* in the API. 适配器使用VS2013编译,但需要支持使用VS2008构建的客户端,因此我在API中使用const char *。 But what I've got isn't working even when both are VS2013-built. 但是,即使两者都是VS2013构建的,我所拥有的也无法工作。

Elsewhere, I found advice to use msclr\\marshal.h, so I created: 在其他地方,我找到了使用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;
}

To test these, I created a round-trip conversion method in my C++/CLI DLL: 为了测试这些,我在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;
}

When the native C++ client calls Foo("abc"), the 1st message gets displayed, the "returned something else" message gets displayed and the client receives junk (îþîþîþîþîþîþîþîþîþîþîþîþîþîþîþîþÞ›vÚ§). 当本机C ++客户端调用Foo(“abc”)时,将显示第一条消息,显示“返回的其他内容”消息,并且客户端收到垃圾邮件(îþîþîþîþîþîþîþîþþþþþþþþþþþþþþþþ>>vÚ§)。 So it would seem my 2nd conversion is not working. 所以看起来我的第二次转换不起作用。

UPDATE UPDATE

Here's the final solution I used. 这是我使用的最终解决方案。

I used zneaks' advice to marshall to std::string and PaulMcKenzie's advice to pass a caller-allocated char* instead of returning const char*. 我使用zneaks的建议来编组std :: string和PaulMcKenzie的建议来传递调用者分配的char *而不是返回const char *。 Thank you both. 谢谢你们俩。

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);
}

The problem is that the marshal_context owns the char pointer that you got, so it is deallocated when your function returns : 问题是marshal_context拥有你得到的char指针,所以当你的函数返回时它会被释放

This example creates a context for marshaling from a System::String to a const char * variable type.The converted data will not be valid after the line that deletes the context. 此示例为从System :: Stringconst char *变量类型的编组创建了一个上下文。转换后的数据在删除上下文的行之后无效。

Consider using marshal_as<std::string> instead, since the string is allowed to outlive the marshal_context . 请考虑使用marshal_as<std::string> ,因为允许该字符串比marshal_context

Additionally, please be aware that VC++ 2008 express does not contains marshal header files (marshal.h and others), so you have to use VC++ 2008 pro or onwards. 另外,请注意VC ++ 2008 express不包含编组头文件(marshal.h和其他),因此您必须使用VC ++ 2008 pro或以上版本。 Looks like those header files are included in express edition since VS2010. 从VS2010开始,看起来这些头文件包含在快递版中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM