如何将 C++/CLI 字符串转换为常量字符*
How to convert C++/CLI string to const char*
我有一个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;
}
为了测试这些,我在 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;
}
当本机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);
}
问题是marshal_context
拥有你得到的 char 指针,所以当你的函数返回时,它被释放:
此示例创建一个上下文,用于将 System::String 封送到 const char * 变量类型。转换后的数据在删除上下文的行之后将无效。
请考虑改用marshal_as<std::string>
,因为允许字符串的寿命超过marshal_context
。
此外,请注意,VC++ 2008 Express 不包含封送头文件(marshal.h 等),因此您必须使用 VC++ 2008 专业版或更高版本。看起来这些头文件自VS2010以来包含在速成版中。
- 是否应避免从非常量迭代器转换为常量迭代器?
- 是否有内置方法可以强制转换为不同的基础类型,但保留常量限定符?
- 为什么我收到"从常量指针到指针的转换无效?
- 从'size_t'转换为"常量双倍",可能会丢失数据
- 在编译时将常量字符* 转换为常量 char_type*
- 为什么下面带有非常量转换函数的代码没有歧义?
- 错误:请求从"常量字符 [5]"转换为非标量类型"字符串"
- 字符串强制转换为常量字符*
- 为什么我可以隐式地将字符*转换为常量字符*,但不能将无符号字符*
- 将错误作为从字符串常量到"char*"的已弃用转换 [-Wwrite-strings]
- 将编译时常量向量转换为堆分配版本
- 在<uint8_t> <char> c++ 中将常量向量转换为常量向量
- 在不同类型之间转换常量指针
- 转换(常量字符*)变量出错
- C++大小写中的类型转换常量字符串
- 转换常量无符号字符无效
- 转换常量表达式定义的说明
- c++ 11强制转换常量迭代器,指向shared_ptr对象的容器
- 条件运算符+上转换+常量引用
- c++限定转换-常量和模板