I am working on a C++/CLI wrapper for a native c++ class. The C++/CLI wrapper is being used in a WPF application. I have encountered a weird problem when trying to marshal strings.
The WPF application passes a System::String object to my wrapper. The wrapper then converts the System::String to a std::string that the native class expects. This all goes fine, but once I pass the string to the native object, it is empty.
Here is some relevant code
WPF Event Handler (C#)
private void tbInputConfig_TextChanged(object sender, TextChangedEventArgs e)
{
_OrionBasicApp.ConfigTemplateFile = tbInputConfig.Text;
}
Property In Wrapper Class (C++/CLI)
void BasicApp::ConfigTemplateFile::set(String ^value)
{
std::string val = marshal_as<std::string>(value);
_NativeApp->setConfigTemplateFile(val);
}
Native Code (C++)
void Basic_App::setConfigTemplateFile(const std::string& template_file)
{
m_gParams.configTemplateFile = template_file;
}
So when I break in the WPF app and trace using the debugger, the String objects look fine, the std::string val marshaling looks good, but the parameter template_file in the setConfigFile function is an empty string. When I step out of the native function, I can see that the std::string val variable still looks fine.
I have tried using Marshal::StringToHGlobalAnsi function, it produces the same result. I have tried changing the native function to take copy of the string instead of a reference, this produces an exception about an invalid block of memory (if requested I will post the exact message). I have tried allocating the string on the heap, no luck.
Now for the kicker: The native code was compiled with Microsoft Visual Studio 2008, and the wrapper + wpf code was compiled with 2010. I hope this is not the problem because it will not be easy for us to migrate either codebase to the other version.
Any ideas?
UPDATE
I was able to switch the native code over to visual studio 2010 and this did fix the problem. (why must microsoft make my life so difficult?) While I did make the system build, the lead on the project is giving me MAJOR hassles about this solution (he is concerned that it may not run correctly or that we will have to switch over dependent libraries).
SO is there a solution to this problem that doesn’t force me to switch visual studio version?
Passing C++ objects across DLL boundaries is a bad idea.
std::stringis not the same type, layout, or implementation, which is causing your problem.If you pass either a BSTR (
SysStringAllocet al) or rawchar*across the DLL boundary, and convert tostd::stringinside the native code instead of in the wrapper, your problem will go away.This problem is not specific to .NET or C++/CLI. Any attempt to pass
std::stringinstances to your native DLL from any other compiler version will fail.Example fix: