将 String^ 转换为 wstring C++
Posted
技术标签:
【中文标题】将 String^ 转换为 wstring C++【英文标题】:Convert a String^ to wstring C++ 【发布时间】:2012-12-12 09:56:59 【问题描述】:我用 C++ 编写了一个小应用程序。 UI 中有一个 ListBox。我想将 ListBox 的选定项用于只能使用 wstrings 的算法。
总而言之,我有两个问题: -我怎样才能转换我的
String^ curItem = listBox2->SelectedItem->ToString();
到 wstring 测试?
-代码中的^是什么意思?
非常感谢!
【问题讨论】:
这是这个问题的副本:***.com/questions/13665649/… 此外,^ 是 C++/CLI 句柄,类似于标准 C++ 中的 * 概念。它称为句柄,表示该对象是一个 .Net 对象。 这是 托管 C++ 又名 C++/CLI 吗? @MauriceReeves 我不认为这是重复的,因为它与转换为 wstring 无关!感谢您提供有关 ^ 的信息 @ulidtko 是的,它是一个 C++/CLI 应用程序 Need to convert String^ to char *的可能重复 【参考方案1】:应该很简单:
std::wstring result = msclr::interop::marshal_as<std::wstring>(curItem);
您还需要头文件来完成这项工作:
#include <msclr\marshal.h>
#include <msclr\marshal_cppstd.h>
对于好奇的人来说,这个marshal_as
专业化的内部是什么样子的:
#include <vcclr.h>
pin_ptr<WCHAR> content = PtrToStringChars(curItem);
std::wstring result(content, curItem->Length);
这是因为System::String
在内部存储为宽字符。如果你想要一个std::string
,你必须使用例如执行 Unicode 转换。 WideCharToMultiByte
。方便marshal_as
为您处理所有细节。
【讨论】:
谢谢 Ben Voigt - 我会测试一下 - 给我 5 分钟 :-) 本你能告诉我我从哪里得到 marshal_as 吗?我也包含头文件 @user1557170:哎呀,你需要第二个头文件。对此感到抱歉。 我现在有点困惑 - 你能简单地告诉我我需要哪些代码吗?我不是像你这样的专业程序员 @Robinson:有两组转换,需要清理的一组需要您创建一个marshal_context
实例,当它超出范围时执行清理。不需要清理的那些(因为它们返回一个智能对象,例如知道如何清理自己的std::string
)使用marshal_as
。除非您做一些疯狂的事情,例如故意泄漏marshal_context
对象,否则您不会出错。【参考方案2】:
我将此标记为重复,但这里是关于如何从 System.String^
到 std::string
的答案。
String^ test = L"I am a .Net string of type System::String";
IntPtr ptrToNativeString = Marshal::StringToHGlobalAnsi(test);
char* nativeString = static_cast<char*>(ptrToNativeString.ToPointer());
诀窍是确保您使用互操作和编组,因为您必须跨越从托管代码到非托管代码的边界。
【讨论】:
呸。我拒绝重新发明这个特殊的***,特别是因为重新发明使用了错误命名的函数。这里根本没有HGLOBAL
。使用该代码是文档的噩梦,因为您必须编写 cmets 来解释非 HGLOBAL 指针实际上是什么。
其实你的回答要好很多。我需要研究 marshal_as 方法。 +1。感谢您指路。
我真的需要一些帮助来消除(嗯,否决)每个建议 StringToHGlobalAnsi
的答案。但这是另一天的工作。
这将是困难的,因为这是甚至微软推荐的此类问题的答案:msdn.microsoft.com/en-us/library/…
那是StringToHGlobalAnsi
页面,他们必须使用该功能。绝不是某个地方的示例表明这是执行任务的最佳方式。【参考方案3】:
我的版本是:
Platform::String^ str = L"my text";
std::wstring wstring = str->Data();
【讨论】:
我收到error C2039: 'Data' : is not a member of 'System::String'
这项工作在 WinRT 上使用 C++/CX
而不是在旧版 CLR 上使用 C++/CLI
。
我喜欢这个,因为这是直截了当的:String^
在 UTF16 中,如果 std::wstring
也应该保留在 UTF16 中 - 不需要转换,只需简单的旧字符副本即可。投票赞成。【参考方案4】:
使用 Visual Studio 2015,只需执行以下操作:
String^ s = "Bonjour!";
C++/CLI
#include <vcclr.h>
pin_ptr<const wchar_t> ptr = PtrToStringChars(s);
C++/CX
const wchart_t* ptr = s->Data();
【讨论】:
【参考方案5】:根据微软:
参考How to: Convert System::String to Standard String
您可以将字符串转换为 std::string 或 std::wstring,而无需在 Vcclr.h 中使用 PtrToStringChars。
// convert_system_string.cpp
// compile with: /clr
#include <string>
#include <iostream>
using namespace std;
using namespace System;
void MarshalString ( String ^ s, string& os )
using namespace Runtime::InteropServices;
const char* chars =
(const char*)(Marshal::StringToHGlobalAnsi(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
void MarshalString ( String ^ s, wstring& os )
using namespace Runtime::InteropServices;
const wchar_t* chars =
(const wchar_t*)(Marshal::StringToHGlobalUni(s)).ToPointer();
os = chars;
Marshal::FreeHGlobal(IntPtr((void*)chars));
int main()
string a = "test";
wstring b = L"test2";
String ^ c = gcnew String("abcd");
cout << a << endl;
MarshalString(c, a);
c = "efgh";
MarshalString(c, b);
cout << a << endl;
wcout << b << endl;
输出:
test
abcd
efgh
【讨论】:
以上是关于将 String^ 转换为 wstring C++的主要内容,如果未能解决你的问题,请参考以下文章
C++ 使用最少的代码将字符串转换为 wstring 并返回
将 std::string 转换为 std::wstring 时,C++17 codecvt 抛出“错误转换”