在char*和System:: c++ /CLI中的字符串之间进行转换的最佳方式是什么

时间:2022-04-15 16:07:02

What is the approved way to convert from char* to System::string and back in C++/CLI? I found a few references to marshal_to<> templated functions on Google, but it appears that this feature never made the cut for Visual Studio 2005 (and isn't in Visual Studio 2008 either, AFAIK). I have also seen some code on Stan Lippman's blog, but it's from 2004. I have also seen Marshal::StringToHGlobalAnsi(). Is there a method that is considered "best practice"?

在c++ /CLI中,从char*转换到System::string和back的批准方式是什么?我在谷歌上发现了一些对marshal_to<>模板化函数的引用,但是看起来这个特性并没有在Visual Studio 2005中出现(也没有在Visual Studio 2008 AFAIK中出现)。我也在Stan Lippman的博客上看到过一些代码,但那是2004年的。我也见过Marshal::StringToHGlobalAnsi()。有没有一种方法被认为是“最佳实践”?

5 个解决方案

#1


18  

There's a good overview here (this marshaling support added for VS2008): http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx

这里有一个很好的概述(对VS2008添加的封送支持):http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx

#2


70  

System::String has a constructor that takes a char*:

系统:::String有一个接受char*的构造函数:

 using namespace system;
 const char* charstr = "Hello, world!";
 String^ clistr = gcnew String(charstr);
 Console::WriteLine(clistr);

Getting a char* back is a bit harder, but not too bad:

要得到一个炭*回去有点困难,但也不是太坏:

 IntPtr p = Marshal::StringToHGlobalAnsi(clistr);
 char *pNewCharStr = static_cast<char*>(p.ToPointer());
 cout << pNewCharStr << endl;
 Marshal::FreeHGlobal(p);

#3


1  

What we did is made a C++\CLI object that held the string in unmangaed code and would give out manged copies of the item. The conversion code looks very much like what Stan has on his blog (I can't remember it exactly)(If you use his code make sure you update it to use delete[]) but we made sure that the destructor would handle releasing all the unmanged elements of the object. This is a little overblown but we didn't have leaks when we tied into legacy C++ code modules.

我们所做的是创建一个c++ \CLI对象,该对象将字符串保存在未使用mangaed代码中,并将给出项目的manged副本。转换代码看起来很像Stan在他的博客上写的(我记不太清楚)(如果你用他的代码确保你更新它来使用delete[]),但是我们确保析构函数会处理释放对象的所有未赋值元素。这有点过分了,但是当我们绑定到遗留的c++代码模块时,并没有出现泄漏。

#4


1  

I created a few helper methods. I needed to do this to move from an old Qt library to CLI String. If anyone can add onto this and tell me if it seems like I have a memory leak and what I can do to fix it, I would be most appreciative.

我创建了一些辅助方法。我需要这样做才能从一个旧的Qt库转移到CLI字符串。如果有人能加到这个,告诉我好像我有内存泄漏,我能做什么来修复它,我会非常感激。

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;
}

#5


0  

One additional link to a summary of possible ways:

另一个链接到可能的方法总结:

http://support.microsoft.com/?kbid=311259

http://support.microsoft.com/?kbid=311259

#1


18  

There's a good overview here (this marshaling support added for VS2008): http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx

这里有一个很好的概述(对VS2008添加的封送支持):http://www.codeproject.com/KB/mcpp/OrcasMarshalAs.aspx

#2


70  

System::String has a constructor that takes a char*:

系统:::String有一个接受char*的构造函数:

 using namespace system;
 const char* charstr = "Hello, world!";
 String^ clistr = gcnew String(charstr);
 Console::WriteLine(clistr);

Getting a char* back is a bit harder, but not too bad:

要得到一个炭*回去有点困难,但也不是太坏:

 IntPtr p = Marshal::StringToHGlobalAnsi(clistr);
 char *pNewCharStr = static_cast<char*>(p.ToPointer());
 cout << pNewCharStr << endl;
 Marshal::FreeHGlobal(p);

#3


1  

What we did is made a C++\CLI object that held the string in unmangaed code and would give out manged copies of the item. The conversion code looks very much like what Stan has on his blog (I can't remember it exactly)(If you use his code make sure you update it to use delete[]) but we made sure that the destructor would handle releasing all the unmanged elements of the object. This is a little overblown but we didn't have leaks when we tied into legacy C++ code modules.

我们所做的是创建一个c++ \CLI对象,该对象将字符串保存在未使用mangaed代码中,并将给出项目的manged副本。转换代码看起来很像Stan在他的博客上写的(我记不太清楚)(如果你用他的代码确保你更新它来使用delete[]),但是我们确保析构函数会处理释放对象的所有未赋值元素。这有点过分了,但是当我们绑定到遗留的c++代码模块时,并没有出现泄漏。

#4


1  

I created a few helper methods. I needed to do this to move from an old Qt library to CLI String. If anyone can add onto this and tell me if it seems like I have a memory leak and what I can do to fix it, I would be most appreciative.

我创建了一些辅助方法。我需要这样做才能从一个旧的Qt库转移到CLI字符串。如果有人能加到这个,告诉我好像我有内存泄漏,我能做什么来修复它,我会非常感激。

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;
}

#5


0  

One additional link to a summary of possible ways:

另一个链接到可能的方法总结:

http://support.microsoft.com/?kbid=311259

http://support.microsoft.com/?kbid=311259