C++/CLI字符串互操作

Max*_*ich 5 c# string wpf interop c++-cli

我正在为本机c ++类开发C++/CLI包装器.C++/CLI包装器正在WPF应用程序中使用.我在尝试编组字符串时遇到了一个奇怪的问题.

WPF应用程序将System::String对象传递给我的包装器.该包装然后转换System::Stringstd::string了本机类的期望.这一切都很顺利,但是一旦我将字符串传递给本机对象,它就是空的.

这是一些相关的代码

WPF事件处理程序(C#)

private void tbInputConfig_TextChanged(object sender, TextChangedEventArgs e)
{
    _OrionBasicApp.ConfigTemplateFile = tbInputConfig.Text;
}
Run Code Online (Sandbox Code Playgroud)

包装类中的属性(C++/CLI)

void BasicApp::ConfigTemplateFile::set(String ^value)
{
    std::string val = marshal_as<std::string>(value);
    _NativeApp->setConfigTemplateFile(val);
}
Run Code Online (Sandbox Code Playgroud)

本地代码(C++)

void Basic_App::setConfigTemplateFile(const std::string& template_file)
{
   m_gParams.configTemplateFile = template_file;
}
Run Code Online (Sandbox Code Playgroud)

所以,当我在WPF应用程序突破和使用调试器的跟踪中,字符串对象看起来很好,在std::string val编组看起来不错,但参数template_filesetConfigFile函数是一个空字符串.当我退出本机函数时,我可以看到std::string val变量看起来仍然很好.

我尝试过使用Marshal::StringToHGlobalAnsi函数,它会产生相同的结果.我已经尝试更改本机函数以获取字符串的副本而不是引用,这会产生关于无效内存块的异常(如果请求,我将发布确切的消息).我试过在堆上分配字符串,没有运气.

现在为踢球者:本机代码是用Microsoft Visual Studio 2008编译的,而包装器+ wpf代码是用2010编译的.我希望这不是问题,因为我们将代码库迁移到其他版本并不容易.

有任何想法吗?

UPDATE

我能够将本机代码切换到visual studio 2010,这确实解决了问题.(为什么微软必须让我的生活变得如此困难?)虽然我确实建立了系统,但是项目的主角给了我关于这个解决方案的主要麻烦(他担心它可能无法正常运行或我们将不得不切换依赖库).

那么这个问题的解决方案是不是迫使我转换Visual Studio版本?

Ben*_*igt 6

跨DLL边界传递C++对象是个坏主意. std::string不是同一类型,布局或实现,这是导致您的问题.

如果您传递BSTR(SysStringAlloc等)或原始char*跨越DLL边界,并转换std::string为本机代码而不是包装器内部,您的问题将消失.

此问题不是特定于.NET或C++/CLI.任何将std::string实例从任何其他编译器版本传递到本机DLL的尝试都将失败.

示例修复:

void BasicApp::ConfigTemplateFile::set(String ^value)
{
    std::string val = marshal_as<std::string>(value);
    _NativeApp->setConfigTemplateFile(val.c_str(), val.size());
}

void Basic_App::setConfigTemplateFile(const char* template_file_content, size_t template_file_length)
{
   m_gParams.configTemplateFile = std::string(template_file_content, template_file_length);
}
Run Code Online (Sandbox Code Playgroud)