#include <string>
#include <msclr/marshal_cppstd.h>
ref class Test {
System::String^ text;
void Method() {
std::string f = msclr::interop::marshal_as<std::string>(text); // line 8
}
};
This code when compiled with VS2008 gives:
.\test.cpp(8) : error C2665: 'msclr::interop::marshal_as' : none of the 3 overloads could convert all the argument types
f:\programy\vs9\vc\include\msclr\marshal.h(153): could be '_To_Type msclr::interop::marshal_as<std::string>(const char [])'
with
[
_To_Type=std::string
]
f:\programy\vs9\vc\include\msclr\marshal.h(160): or '_To_Type msclr::interop::marshal_as<std::string>(const wchar_t [])'
with
[
_To_Type=std::string
]
f:\Programy\VS9\VC\include\msclr/marshal_cppstd.h(35): or 'std::string msclr::interop::marshal_as<std::string,System::String^>(System::String ^const &)'
while trying to match the argument list '(System::String ^)'
But when I change the field into property:
property System::String^ text;
then this code compiles without errors. Why?
A workaround is to make a copy like this:
ref class Test {
System::String^ text;
void Method() {
System::String^ workaround = text;
std::string f = msclr::interop::marshal_as<std::string>(workaround);
}
};
Bug, fixed in VS2010. Feedback item is here.
I'm using this snippet a lot, and it's too much clutter to declare a new variable. However this works too:
msclr::interop::marshal_as<std::string>(gcnew String(string_to_be_converted))
Another option that works for me is this little template. Not only does it solve the bug discussed here, it also fixes another thing that's broken with marshal_as, namely that it does not work for nullptr input. But actually a good c++ translation for a nullptr System::String would be an .empty() std::string(). Here is the template:
template<typename ToType, typename FromType>
inline ToType frum_cast(FromType s)
{
if (s == nullptr)
return ToType();
return msclr::interop::marshal_as<ToType>(s);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With