Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/141.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何转换C++/CLI字符串到常量字符* 我有一个C++/CLI DLL,我打算用它作为C++的一个适配器和本地C++客户端之间的适配器。我需要在两个方向传递字符串。适配器是用VS2013编译的,但需要支持用VS2008构建的客户端,所以我在API中使用const char*。但即使两个都是VS2013构建的,我得到的也不起作用_C#_C++_C_Dll - Fatal编程技术网

C# 如何转换C++/CLI字符串到常量字符* 我有一个C++/CLI DLL,我打算用它作为C++的一个适配器和本地C++客户端之间的适配器。我需要在两个方向传递字符串。适配器是用VS2013编译的,但需要支持用VS2008构建的客户端,所以我在API中使用const char*。但即使两个都是VS2013构建的,我得到的也不起作用

C# 如何转换C++/CLI字符串到常量字符* 我有一个C++/CLI DLL,我打算用它作为C++的一个适配器和本地C++客户端之间的适配器。我需要在两个方向传递字符串。适配器是用VS2013编译的,但需要支持用VS2008构建的客户端,所以我在API中使用const char*。但即使两个都是VS2013构建的,我得到的也不起作用,c#,c++,c,dll,C#,C++,C,Dll,在别处,我找到了使用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\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++客户端调用FO(“abc”)时,第一个消息被显示,“返回的其他消息”被显示,客户端接收到垃圾邮件。看来我的第二次转换不起作用了

更新

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

我使用zneaks的建议将marshall改为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);
}
void tocpstring(系统::String^输入,char*输出)
{
std::string temp=marshal_as(输入);
strcpy(输出,温度c_str());
}
void Foo(常量字符*输入,字符*输出)
{
系统::字符串^cli=::ToCliString(输入);
::tocpString(cli,输出);
}

问题在于
封送上下文
拥有您获得的字符指针,因此:

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


考虑改用,因为允许字符串在
封送\u上下文

之外存在,请注意VC++2008 express不包含封送头文件(marshal.h和其他文件),因此您必须使用VC++2008 pro或更高版本。看起来,自从VS2010以来,这些头文件都包含在Express版本中。

你返回一个指向本地变量的指针<代码> cSt2,这是未定义的行为。@ PulcMcKeZi]因此,将一个字符串从C ^传递到本地C++客户端,客户端需要通过一个字符适配器适配器“填充”,这是通常的方式。客户端提供缓冲区,C++代码将缓冲区填充到数据中。@ PulcMcKeZee客户端是否需要调用Delphi来防止内存泄漏?我想他们可以分配一次缓冲区,在我的API中调用许多函数,并在完成后删除。所以我的API应该包含另一个parm,这样他们就可以告诉我可以返回的最大消息大小了?或者更适合让属性客户端可以查询以确定我的最大消息长度?客户端负责正确维护缓冲区。它可能被分配了
new[]/delete[]
,它甚至可能是一个
std::vector
,您正在传递
std::vector::data()
,等等。我刚刚尝试用std::string result=context.marshal_as替换tocpstring的最后两行;返回result.c_str();但同样的结果。我想知道,既然本地std::string超出了作用域,那么它的c_str()函数返回的值是否仍然有效?明白了,现在在新参数中使用strcpy。稍后将发布我的解决方案。@JimC,是的,
c_str()
返回的指针归字符串所有,并在函数返回时解除分配,因此您基本上又遇到了相同的问题。不过,您可以返回一个
std::string
。我可以,但这只是在踢罐子,因为我无法将std::string全部返回到应用程序(我必须支持使用不同版本的Visual Studio构建的应用程序)。请小心自己删除字符串。
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);
}