问题描述
|
我正在调用c ++库,并且正在围绕该库编写托管的C ++包装器类。该方法使用QString的参数,有时还引用QString,以便可以填充该值。方法声明不存在。因此,现在我尝试传递System :: String,但是我不知道如何将其转换为QString。因此,此问题的答案可以采用以下两种形式之一。 1.为什么我不能将c#中的方法引用到具有std :: string参数的托管C ++代码中?或者,如何将System :: String转换为QString?
解决方法
为什么我不能将c#中的方法引用到具有std :: string参数的托管C ++代码中?
只有POD类型可以在本机代码和托管代码之间自动来回编组。
std::string
不是POD类型。
或者,如何将System :: String转换为QString?
#include <string>
#include <QString>
#include <msclr/marshal_cppstd.h>
QString SystemStringToQString(System::String^ str)
{
using namespace msclr::interop;
return QString::fromStdWString(marshal_as<std::wstring>(str));
}
编辑(响应对答案#6205169的评论):
建议的内存泄漏修复程序:
std::wstring MarshalString(String^ s)
{
using namespace System::Runtime::InteropServices;
std::wstring ret;
IntPtr p = Marshal::StringToHGlobalUni(s);
if (p.ToPointer())
{
ret.assign((wchar_t const*)p.ToPointer());
Marshal::FreeHGlobal(p);
}
return ret;
}
从性能角度来看,这效率远不如预期,但它应该有效并且不应泄漏。
,看到这个:
http://www.codeguru.com/forum/showthread.php?t=372298
它应该使您降至char*
,可以轻松转换为QString
。
,好吧,我在那儿。我只需要知道这些方法是否会造成内存泄漏,我该怎么办
我创建了一些辅助方法来执行此操作。我需要执行此操作才能从旧的Qt库移至CLI字符串。我无法更新Qt库,因为我对代码的这一部分没有任何控制权。
void MarshalString ( String ^ s,wstring& os ) {
using namespace Runtime::InteropServices;
const wchar_t* char =
(const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
os = char;
}
QString SystemStringToQt( System::String^ str)
{
wstring t;
MarshalString(str,t);
QString r = QString::fromUcs2((const ushort*)t.c_str());
return r;
}
String ^ QtToSystemString( QString * str)
{
wchar_t * wcar = (wchar_t *)str->ucs2();
String^ r = gcnew String(wcar);
return r;
}