我正在调用一个c ++ lib,并在lib周围编写一个托管C ++包装器类。这些方法接受QString的参数,有时引用QString,以便可以填充该值。我尝试使用std :: string,看起来没问题,直到我编译它并将其链接到c#,就像方法声明一样不存在。所以现在我试图传入System :: String但我无法弄清楚如何将其转换为QString。因此,这个问题的答案可以采用两种形式之一。 1.为什么我不能将c#中的方法引用到具有std :: string参数的托管c ++代码中?或者,如何将System :: String转换为QString?
答案 0 :(得分:3)
为什么我不能将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;
}
在性能方面,这远远低于它可能的效率,但它应该工作且不应泄漏。
答案 1 :(得分:0)
答案 2 :(得分:0)
好吧,我在那里。我只需要知道这些方法是否会造成内存泄漏以及我能做些什么
我创建了一些辅助方法来执行此操作。我需要这样做才能从旧的Qt库迁移到CLI String。我无法更新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;
}