本文介绍如何将各种 Visual C++ 字符串类型转换为其他字符串。

涵盖的字符串类型包括 char * wchar_t* _bstr_t CComBSTR CString basic_string System.String

在所有情况下,当转换为新类型时,将创建字符串的副本。 对新字符串所做的任何更改都不会影响原始字符串,反之亦然。

有关转换窄字符串和宽字符串的更多背景信息,请参阅 窄字符串与宽字符串之间的转换

若要在 Visual Studio 2022 中运行示例,可以创建新的 C++ Windows 控制台应用。 或者,如果已安装 C++/CLI 支持,则可以创建 CLR 控制台应用 (.NET Framework) 。

如果创建 CLR 控制台应用,不需要对编译器和调试器设置进行以下更改。 但是,需要将 #include "pch.h" 添加到每个示例的顶部。

无论通过哪种方式,都要将 comsuppw.lib 添加到“项目属性”>“链接器”>“输入”>“其他依赖项”。

如果创建新的 C++ Windows 控制台应用以运行示例,请对项目进行以下更改:

  • /clr /Zc:twoPhase- 命令行参数添加到“项目属性”>“C++”>“命令行”>“其他选项”。
  • /clr 开关与你创建 C++ Windows 控制台应用项目时设置的一些编译器开关冲突。 以下链接内容说明了可以在 IDE 中的哪些位置关闭存在冲突的开关:

  • 关闭 /RTC1 (将基本运行时检查设置为默认) 项目属性 > C/C++ > 代码生成 > 基本运行时检查 > 默认值
  • 关闭 /EHs (异常处理模型) 项目属性 > C/C++ > 代码生成 > 启用 C++ 异常 >
  • Exchange /Zi (调试信息格式) /Z7 项目属性 > C/C++ > 通用 > 调试信息格式 > C7 兼容
  • 关闭 /JMC (仅我的代码调试) 项目属性 > C/C++ > 常规 > 支持仅我的代码调试 >
  • 将调试器类型设置为混合:“项目属性”>“调试”>“调试器类型”>“混合(.NET Framework)”
  • 打开 /ASSEMBLYDEBUG 项目属性 > 链接器 > 调试 > 可调试程序集 > 是 (ASSEMBLYDEBUG)
  • 示例:从 char * 转换

    此示例演示了如何从 char * 转换为上面列出的字符串类型。 char * 字符串(也称为 C 样式字符串)使用终止 null 来指示字符串的结尾。 C 样式字符串通常需要每个字符使用 1 个字节,但也可以使用 2 个字节。 在下面的示例中, char * 字符串有时被称为多字节字符串,因为字符串数据是从宽 Unicode 字符串转换而来的。 单字节和多字节字符 ( MBCS ) 函数可以对 char * 字符串进行操作。

    有关运行和调试此示例的信息,请参阅 运行示例

    // convert_from_char.cpp
    // compile with: /clr /Zc:twoPhase- /link comsuppw.lib
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include "atlbase.h"
    #include "atlstr.h"
    #include "comutil.h"
    using namespace std;
    using namespace System;
    int main()
        // Create and display a C-style string, and then use it
        // to create different kinds of strings.
        const char* orig = "Hello, World!";
        cout << orig << " (char *)" << endl;
        // newsize describes the length of the
        // wchar_t string called wcstring in terms of the number
        // of wide characters, not the number of bytes.
        size_t newsize = strlen(orig) + 1;
        // The following creates a buffer large enough to contain
        // the exact number of characters in the original string
        // in the new format. If you want to add more characters
        // to the end of the string, increase the value of newsize
        // to increase the size of the buffer.
        wchar_t* wcstring = new wchar_t[newsize];
        // Convert char* string to a wchar_t* string.
        size_t convertedChars = 0;
        mbstowcs_s(&convertedChars, wcstring, newsize, orig, _TRUNCATE);
        // Display the result and indicate the type of string that it is.
        wcout << wcstring << L" (wchar_t *)" << endl;
        delete []wcstring;
        // Convert the C-style string to a _bstr_t string.
        _bstr_t bstrt(orig);
        // Append the type of string to the new string
        // and then display the result.
        bstrt += " (_bstr_t)";
        cout << bstrt << endl;
        // Convert the C-style string to a CComBSTR string.
        CComBSTR ccombstr(orig);
        if (ccombstr.Append(L" (CComBSTR)") == S_OK)
            CW2A printstr(ccombstr);
            cout << printstr << endl;
        // Convert the C-style string to a CStringA and display it.
        CStringA cstringa(orig);
        cstringa += " (CStringA)";
        cout << cstringa << endl;
        // Convert the C-style string to a CStringW and display it.
        CStringW cstring(orig);
        cstring += " (CStringW)";
        // To display a CStringW correctly, use wcout and cast cstring
        // to (LPCTSTR).
        wcout << (LPCTSTR)cstring << endl;
        // Convert the C-style string to a basic_string and display it.
        string basicstring(orig);
        basicstring += " (basic_string)";
        cout << basicstring << endl;
        // Convert the C-style string to a System::String and display it.
        String^ systemstring = gcnew String(orig);
        systemstring += " (System::String)";
        Console::WriteLine("{0}", systemstring);
        delete systemstring;
    
    Hello, World! (char *)
    Hello, World! (wchar_t *)
    Hello, World! (_bstr_t)
    Hello, World! (CComBSTR)
    Hello, World! (CStringA)
    Hello, World! (CStringW)
    Hello, World! (basic_string)
    Hello, World! (System::String)
    

    示例:从 wchar_t * 转换

    此示例演示了如何从 wchar_t * 转换为其他字符串类型。 一些字符串类型(包括 wchar_t *)实现了宽字符格式。 若要在多字节和宽字符格式之间转换字符串,可以使用像 mbstowcs_s 这样的单个函数调用或像 CStringA 这样的类的构造函数调用。

    有关运行和调试此示例的信息,请参阅运行示例

    // convert_from_wchar_t.cpp
    // compile with: /clr /Zc:twoPhase- /link comsuppw.lib
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include "atlbase.h"
    #include "atlstr.h"
    #include "comutil.h"
    using namespace std;
    using namespace System;
    int main()
        // Create a string of wide characters, display it, and then
        // use this string to create other types of strings.
        const wchar_t* orig = L"Hello, World!";
        wcout << orig << L" (wchar_t *)" << endl;
        // Convert the wchar_t string to a char* string. Record
        // the length of the original string and add 1 to it to
        // account for the terminating null character.
        size_t origsize = wcslen(orig) + 1;
        size_t convertedChars = 0;
        // Use a multibyte string to append the type of string
        // to the new string before displaying the result.
        char strConcat[] = " (char *)";
        size_t strConcatsize = (strlen(strConcat) + 1) * 2;
        // Allocate two bytes in the multibyte output string for every wide
        // character in the input string (including a wide character
        // null). Because a multibyte character can be one or two bytes,
        // you should allot two bytes for each character. Having extra
        // space for the new string isn't an error, but having
        // insufficient space is a potential security problem.
        const size_t newsize = origsize * 2;
        // The new string will contain a converted copy of the original
        // string plus the type of string appended to it.
        char* nstring = new char[newsize + strConcatsize];
        // Put a copy of the converted string into nstring
        wcstombs_s(&convertedChars, nstring, newsize, orig, _TRUNCATE);
        // append the type of string to the new string.
        _mbscat_s((unsigned char*)nstring, newsize + strConcatsize, (unsigned char*)strConcat);
        // Display the result.
        cout << nstring << endl;
        delete []nstring;
        // Convert a wchar_t to a _bstr_t string and display it.
        _bstr_t bstrt(orig);
        bstrt += " (_bstr_t)";
        cout << bstrt << endl;
        // Convert the wchar_t string to a BSTR wide character string
        // by using the ATL CComBSTR wrapper class for BSTR strings.
        // Then display the result.
        CComBSTR ccombstr(orig);
        if (ccombstr.Append(L" (CComBSTR)") == S_OK)
            // CW2A converts the string in ccombstr to a multibyte
            // string in printstr, used here for display output.
            CW2A printstr(ccombstr);
            cout << printstr << endl;
            // The following line of code is an easier way to
            // display wide character strings:
            wcout << (LPCTSTR)ccombstr << endl;
        // Convert a wide wchar_t string to a multibyte CStringA,
        // append the type of string to it, and display the result.
        CStringA cstringa(orig);
        cstringa += " (CStringA)";
        cout << cstringa << endl;
        // Convert a wide character wchar_t string to a wide
        // character CStringW string and append the type of string to it
        CStringW cstring(orig);
        cstring += " (CStringW)";
        // To display a CStringW correctly, use wcout and cast cstring
        // to (LPCTSTR).
        wcout << (LPCTSTR)cstring << endl;
        // Convert the wide character wchar_t string to a
        // basic_string, append the type of string to it, and
        // display the result.
        wstring basicstring(orig);
        basicstring += L" (basic_string)";
        wcout << basicstring << endl;
        // Convert a wide character wchar_t string to a
        // System::String string, append the type of string to it,
        // and display the result.
        String^ systemstring = gcnew String(orig);
        systemstring += " (System::String)";
        Console::WriteLine("{0}", systemstring);
        delete systemstring;
    
    Hello, World! (wchar_t *)
    Hello, World! (char *)
    Hello, World! (_bstr_t)
    Hello, World! (CComBSTR)
    Hello, World! (CStringA)
    Hello, World! (CStringW)
    Hello, World! (basic_string)
    Hello, World! (System::String)
    

    示例:从 _bstr_t 转换

    此示例演示了如何从 _bstr_t 转换为其他字符串类型。 _bstr_t 对象封装宽字符 BSTR 字符串。 BSTR 字符串具有长度值,并且不使用 null 字符终止字符串,但要转换为的字符串类型可能需要终止 null 字符。

    有关运行和调试此示例的信息,请参阅运行示例

    // convert_from_bstr_t.cpp
    // compile with: /clr /Zc:twoPhase- /link comsuppw.lib
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include "atlbase.h"
    #include "atlstr.h"
    #include "comutil.h"
    using namespace std;
    using namespace System;
    int main()
        // Create a _bstr_t string, display the result, and indicate the
        // type of string that it is.
        _bstr_t orig("Hello, World!");
        wcout << orig << " (_bstr_t)" << endl;
        // Convert the wide character _bstr_t string to a C-style
        // string. To be safe, allocate two bytes for each character
        // in the char* string, including the terminating null.
        const size_t newsize = (orig.length() + 1) * 2;
        char* nstring = new char[newsize];
        // Uses the _bstr_t operator (char *) to obtain a null
        // terminated string from the _bstr_t object for
        // nstring.
        strcpy_s(nstring, newsize, (char*)orig);
        strcat_s(nstring, newsize, " (char *)");
        cout << nstring << endl;
        delete []nstring;
        // Prepare the type of string to append to the result.
        wchar_t strConcat[] = L" (wchar_t *)";
        size_t strConcatLen = wcslen(strConcat) + 1;
        // Convert a _bstr_t to a wchar_t* string.
        const size_t widesize = orig.length() + strConcatLen;
        wchar_t* wcstring = new wchar_t[newsize];
        wcscpy_s(wcstring, widesize, (wchar_t*)orig);
        wcscat_s(wcstring, widesize, strConcat);
        wcout << wcstring << endl;
        delete []wcstring;
        // Convert a _bstr_t string to a CComBSTR string.
        CComBSTR ccombstr((char*)orig);
        if (ccombstr.Append(L" (CComBSTR)") == S_OK)
            CW2A printstr(ccombstr);
            cout << printstr << endl;
        // Convert a _bstr_t to a CStringA string.
        CStringA cstringa(orig.GetBSTR());
        cstringa += " (CStringA)";
        cout << cstringa << endl;
        // Convert a _bstr_t to a CStringW string.
        CStringW cstring(orig.GetBSTR());
        cstring += " (CStringW)";
        // To display a cstring correctly, use wcout and
        // "cast" the cstring to (LPCTSTR).
        wcout << (LPCTSTR)cstring << endl;
        // Convert the _bstr_t to a basic_string.
        string basicstring((char*)orig);
        basicstring += " (basic_string)";
        cout << basicstring << endl;
        // Convert the _bstr_t to a System::String.
        String^ systemstring = gcnew String((char*)orig);
        systemstring += " (System::String)";
        Console::WriteLine("{0}", systemstring);
        delete systemstring;
    
    Hello, World! (_bstr_t)
    Hello, World! (char *)
    Hello, World! (wchar_t *)
    Hello, World! (CComBSTR)
    Hello, World! (CStringA)
    Hello, World! (CStringW)
    Hello, World! (basic_string)
    Hello, World! (System::String)
    

    示例:从 CComBSTR 转换

    此示例演示了如何从 CComBSTR 转换为其他字符串类型。 与 _bstr_t 一样,CComBSTR 对象封装宽字符 BSTR 字符串。 BSTR 字符串具有长度值,并且不使用 null 字符终止字符串,但要转换为的字符串类型可能需要终止 null。

    有关运行和调试此示例的信息,请参阅运行示例

    // convert_from_ccombstr.cpp
    // compile with: /clr /Zc:twoPhase- /link comsuppw.lib
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include "atlbase.h"
    #include "atlstr.h"
    #include "comutil.h"
    #include "vcclr.h"
    using namespace std;
    using namespace System;
    using namespace System::Runtime::InteropServices;
    int main()
        // Create and initialize a BSTR string by using a CComBSTR object.
        CComBSTR orig("Hello, World!");
        // Convert the BSTR into a multibyte string, display the result,
        // and indicate the type of string that it is.
        CW2A printstr(orig);
        cout << printstr << " (CComBSTR)" << endl;
        // Convert a wide character CComBSTR string to a
        // regular multibyte char* string. Allocate enough space
        // in the new string for the largest possible result,
        // including space for a terminating null.
        const size_t newsize = (orig.Length() + 1) * 2;
        char* nstring = new char[newsize];
        // Create a string conversion object, copy the result to
        // the new char* string, and display the result.
        CW2A tmpstr1(orig);
        strcpy_s(nstring, newsize, tmpstr1);
        cout << nstring << " (char *)" << endl;
        delete []nstring;
        // Prepare the type of string to append to the result.
        wchar_t strConcat[] = L" (wchar_t *)";
        size_t strConcatLen = wcslen(strConcat) + 1;
        // Convert a wide character CComBSTR string to a wchar_t*.
        // The code first determines the length of the converted string
        // plus the length of the appended type of string, then
        // prepares the final wchar_t string for display.
        const size_t widesize = orig.Length() + strConcatLen;
        wchar_t* wcstring = new wchar_t[widesize];
        wcscpy_s(wcstring, widesize, orig);
        wcscat_s(wcstring, widesize, strConcat);
        // Display the result. Unlike CStringW, a wchar_t doesn't need
        // a cast to (LPCTSTR) with wcout.
        wcout << wcstring << endl;
        delete []wcstring;
        // Convert a wide character CComBSTR to a wide character _bstr_t,
        // append the type of string to it, and display the result.
        _bstr_t bstrt(orig);
        bstrt += " (_bstr_t)";
        cout << bstrt << endl;
        // Convert a wide character CComBSTR to a multibyte CStringA,
        // append the type of string to it, and display the result.
        CStringA cstringa(orig);
        cstringa += " (CStringA)";
        cout << cstringa << endl;
        // Convert a wide character CComBSTR to a wide character CStringW.
        CStringW cstring(orig);
        cstring += " (CStringW)";
        // To display a cstring correctly, use wcout and cast cstring
        // to (LPCTSTR).
        wcout << (LPCTSTR)cstring << endl;
        // Convert a wide character CComBSTR to a wide character
        // basic_string.
        wstring basicstring(orig);
        basicstring += L" (basic_string)";
        wcout << basicstring << endl;
        // Convert a wide character CComBSTR to a System::String.
        String^ systemstring = gcnew String(orig);
        systemstring += " (System::String)";
        Console::WriteLine("{0}", systemstring);
        delete systemstring;
    
    Hello, World! (CComBSTR)
    Hello, World! (char *)
    Hello, World! (wchar_t *)
    Hello, World! (_bstr_t)
    Hello, World! (CStringA)
    Hello, World! (CStringW)
    Hello, World! (basic_string)
    Hello, World! (System::String)
    

    示例:从 CString 转换

    此示例演示了如何从 CString 转换为其他字符串类型。 CString 基于 TCHAR 数据类型,而该数据类型又取决于是否定义了符号 _UNICODE。 如果未定义 _UNICODE,则将 TCHAR 定义为 char,并且 CString 包含一个多字节字符串;如果定义了 _UNICODE,则将 TCHAR 定义为 wchar_t,并且 CString 包含一个宽字符串。

    CStringA 包含 char 类型并支持单字节或多字节字符串。 CStringW 是宽字符版本。 CStringACStringW 不使用 _UNICODE 来确定它们应该如何编译。 此示例中使用了 CStringACStringW 来阐明缓冲区大小分配和输出处理方面的细微差别。

    有关运行和调试此示例的信息,请参阅运行示例

    // convert_from_cstring.cpp
    // compile with: /clr /Zc:twoPhase- /link comsuppw.lib
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include "atlbase.h"
    #include "atlstr.h"
    #include "comutil.h"
    using namespace std;
    using namespace System;
    int main()
        // Set up a multibyte CStringA string.
        CStringA origa("Hello, World!");
        cout << origa << " (CStringA)" << endl;
        // Set up a wide character CStringW string.
        CStringW origw("Hello, World!");
        wcout << (LPCTSTR)origw << L" (CStringW)" << endl;
        // Convert to a char* string from CStringA string
        // and display the result.
        const size_t newsizea = origa.GetLength() + 1;
        char* nstringa = new char[newsizea];
        strcpy_s(nstringa, newsizea, origa);
        cout << nstringa << " (char *)" << endl;
        delete []nstringa;
        // Convert to a char* string from a wide character
        // CStringW string. To be safe, we allocate two bytes for each
        // character in the original string, including the terminating
        // null.
        const size_t newsizew = (origw.GetLength() + 1) * 2;
        char* nstringw = new char[newsizew];
        size_t convertedCharsw = 0;
        wcstombs_s(&convertedCharsw, nstringw, newsizew, origw, _TRUNCATE);
        cout << nstringw << " (char *)" << endl;
        delete []nstringw;
        // Convert to a wchar_t* from CStringA
        size_t convertedCharsa = 0;
        wchar_t* wcstring = new wchar_t[newsizea];
        mbstowcs_s(&convertedCharsa, wcstring, newsizea, origa, _TRUNCATE);
        wcout << wcstring << L" (wchar_t *)" << endl;
        delete []wcstring;
        // Convert to a wide character wchar_t* string from
        // a wide character CStringW string.
        wchar_t* n2stringw = new wchar_t[newsizew];
        wcscpy_s(n2stringw, newsizew, origw);
        wcout << n2stringw << L" (wchar_t *)" << endl;
        delete []n2stringw;
        // Convert to a wide character _bstr_t string from
        // a multibyte CStringA string.
        _bstr_t bstrt(origa);
        bstrt += L" (_bstr_t)";
        wcout << bstrt << endl;
        // Convert to a wide character _bstr_t string from
        // a wide character CStringW string.
        bstr_t bstrtw(origw);
        bstrtw += " (_bstr_t)";
        wcout << bstrtw << endl;
        // Convert to a wide character CComBSTR string from
        // a multibyte character CStringA string.
        CComBSTR ccombstr(origa);
        if (ccombstr.Append(L" (CComBSTR)") == S_OK)
            // Convert the wide character string to multibyte
            // for printing.
            CW2A printstr(ccombstr);
            cout << printstr << endl;
        // Convert to a wide character CComBSTR string from
        // a wide character CStringW string.
        CComBSTR ccombstrw(origw);
        // Append the type of string to it, and display the result.
        if (ccombstrw.Append(L" (CComBSTR)") == S_OK)
            CW2A printstrw(ccombstrw);
            wcout << printstrw << endl;
        // Convert a multibyte character CStringA to a
        // multibyte version of a basic_string string.
        string basicstring(origa);
        basicstring += " (basic_string)";
        cout << basicstring << endl;
        // Convert a wide character CStringW to a
        // wide character version of a basic_string
        // string.
        wstring basicstringw(origw);
        basicstringw += L" (basic_string)";
        wcout << basicstringw << endl;
        // Convert a multibyte character CStringA to a
        // System::String.
        String^ systemstring = gcnew String(origa);
        systemstring += " (System::String)";
        Console::WriteLine("{0}", systemstring);
        delete systemstring;
        // Convert a wide character CStringW to a
        // System::String.
        String^ systemstringw = gcnew String(origw);
        systemstringw += " (System::String)";
        Console::WriteLine("{0}", systemstringw);
        delete systemstringw;
    
    Hello, World! (CStringA)
    Hello, World! (CStringW)
    Hello, World! (char *)
    Hello, World! (char *)
    Hello, World! (wchar_t *)
    Hello, World! (wchar_t *)
    Hello, World! (_bstr_t)
    Hello, World! (_bstr_t)
    Hello, World! (CComBSTR)
    Hello, World! (CComBSTR)
    Hello, World! (basic_string)
    Hello, World! (System::String)
    

    示例:从 basic_string 转换

    此示例演示了如何从 basic_string 转换为其他字符串类型。

    有关运行和调试此示例的信息,请参阅运行示例

    // convert_from_basic_string.cpp
    // compile with: /clr /Zc:twoPhase- /link comsuppw.lib
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include "atlbase.h"
    #include "atlstr.h"
    #include "comutil.h"
    using namespace std;
    using namespace System;
    int main()
        // Set up a basic_string string.
        string orig("Hello, World!");
        cout << orig << " (basic_string)" << endl;
        // Convert a wide character basic_string string to a multibyte char*
        // string. To be safe, we allocate two bytes for each character
        // in the original string, including the terminating null.
        const size_t newsize = (orig.size() + 1) * 2;
        char* nstring = new char[newsize];
        strcpy_s(nstring, newsize, orig.c_str());
        cout << nstring << " (char *)" << endl;
        delete []nstring;
        // Convert a basic_string string to a wide character
        // wchar_t* string. You must first convert to a char*
        // for this to work.
        const size_t newsizew = orig.size() + 1;
        size_t convertedChars = 0;
        wchar_t* wcstring = new wchar_t[newsizew];
        mbstowcs_s(&convertedChars, wcstring, newsizew, orig.c_str(), _TRUNCATE);
        wcout << wcstring << L" (wchar_t *)" << endl;
        delete []wcstring;
        // Convert a basic_string string to a wide character
        // _bstr_t string.
        _bstr_t bstrt(orig.c_str());
        bstrt += L" (_bstr_t)";
        wcout << bstrt << endl;
        // Convert a basic_string string to a wide character
        // CComBSTR string.
        CComBSTR ccombstr(orig.c_str());
        if (ccombstr.Append(L" (CComBSTR)") == S_OK)
            // Make a multibyte version of the CComBSTR string
            // and display the result.
            CW2A printstr(ccombstr);
            cout << printstr << endl;
        // Convert a basic_string string into a multibyte
        // CStringA string.
        CStringA cstring(orig.c_str());
        cstring += " (CStringA)";
        cout << cstring << endl;
        // Convert a basic_string string into a wide
        // character CStringW string.
        CStringW cstringw(orig.c_str());
        cstringw += L" (CStringW)";
        wcout << (LPCTSTR)cstringw << endl;
        // Convert a basic_string string to a System::String
        String^ systemstring = gcnew String(orig.c_str());
        systemstring += " (System::String)";
        Console::WriteLine("{0}", systemstring);
        delete systemstring;
    
    Hello, World! (basic_string)
    Hello, World! (char *)
    Hello, World! (wchar_t *)
    Hello, World! (_bstr_t)
    Hello, World! (CComBSTR)
    Hello, World! (CStringA)
    Hello, World! (CStringW)
    Hello, World! (System::String)
    

    示例:从 System::String 转换

    此示例演示了如何从宽字符 System::String 转换为其他字符串类型。

    有关运行和调试此示例的信息,请参阅运行示例

    // convert_from_system_string.cpp
    // compile with: /clr /Zc:twoPhase- /link comsuppw.lib
    #include <iostream>
    #include <stdlib.h>
    #include <string>
    #include "atlbase.h"
    #include "atlstr.h"
    #include "comutil.h"
    #include "vcclr.h"
    using namespace std;
    using namespace System;
    using namespace System::Runtime::InteropServices;
    int main()
        // Set up a System::String and display the result.
        String^ orig = gcnew String("Hello, World!");
        Console::WriteLine("{0} (System::String)", orig);
        // Obtain a pointer to the System::String in order to
        // first lock memory into place, so that the
        // Garbage Collector (GC) cannot move that object
        // while we call native functions.
        pin_ptr<const wchar_t> wch = PtrToStringChars(orig);
        // Make a copy of the System::String as a multibyte
        // char* string. Allocate two bytes in the multibyte
        // output string for every wide character in the input
        // string, including space for a terminating null.
        size_t origsize = wcslen(wch) + 1;
        const size_t newsize = origsize * 2;
        size_t convertedChars = 0;
        char* nstring = new char[newsize];
        wcstombs_s(&convertedChars, nstring, newsize, wch, _TRUNCATE);
        cout << nstring << " (char *)" << endl;
        delete []nstring;
        // Convert a wide character System::String to a
        // wide character wchar_t* string.
        const size_t newsizew = origsize;
        wchar_t* wcstring = new wchar_t[newsizew];
        wcscpy_s(wcstring, newsizew, wch);
        wcout << wcstring << L" (wchar_t *)" << endl;
        delete []wcstring;
        // Convert a wide character System::String to a
        // wide character _bstr_t string.
        _bstr_t bstrt(wch);
        bstrt += " (_bstr_t)";
        cout << bstrt << endl;
        // Convert a wide character System::String
        // to a wide character CComBSTR string.
        CComBSTR ccombstr(wch);
        if (ccombstr.Append(L" (CComBSTR)") == S_OK)
            // Make a multibyte copy of the CComBSTR string
            // and display the result.
            CW2A printstr(ccombstr);
            cout << printstr << endl;
        // Convert a wide character System::String to
        // a multibyte CStringA string.
        CStringA cstring(wch);
        cstring += " (CStringA)";
        cout << cstring << endl;
        // Convert a wide character System::String to
        // a wide character CStringW string.
        CStringW cstringw(wch);
        cstringw += " (CStringW)";
        wcout << (LPCTSTR)cstringw << endl;
        // Convert a wide character System::String to
        // a wide character basic_string.
        wstring basicstring(wch);
        basicstring += L" (basic_string)";
        wcout << basicstring << endl;
        delete orig;
    
    Hello, World! (System::String)
    Hello, World! (char *)
    Hello, World! (wchar_t *)
    Hello, World! (_bstr_t)
    Hello, World! (CComBSTR)
    Hello, World! (CStringA)
    Hello, World! (CStringW)
    Hello, World! (basic_string)
    

    在窄字符串和宽字符串之间转换

    传统的 C 和 Windows 应用在处理窄字符串和宽字符串时使用代码页而不是 Unicode 编码。

    .NET 字符串是 UTF-16,但 ATL 的 CStringA 是一个窄字符串,由 WideCharToMultiByte Win32 函数执行从宽到窄的转换。 将 C 样式的 CHAR*(C 样式的 CHAR* 是 .NET byte*)转换为字符串时,会调用相反的 Win32 函数 MultiByteToWideChar

    这两个函数都依赖于代码页的 Windows 概念;不是区域性的 .NET 概念。 若要更改系统代码页,请通过以下方式使用区域设置:使用“控制面板”> 在搜索框中输入 Region>“区域(更改日期、时间或数字格式)”>“管理”>“更改系统区域设置”。

    en-US 语言版本的 Windows 上,代码页默认为 1033。 如果安装其他语言的 Windows,它将具有不同的代码页。 可以使用控制面板来更改它。

    CStringA 执行宽到窄转换的方式与 gcnew string(CHAR*) 执行窄到宽转换的方式不一致。 CStringACP_THREAD_ACP(也就是使用当前线程代码页,)传递给收缩转换方法。 但是 string.ctor(sbyte*)CP_ACP(也就是使用当前系统代码页)传递给扩大转换方法。 如果系统和线程代码页不匹配,就会导致往返数据损坏。

    为了协调这种差异,请使用常量 (_CONVERSION_DONT_USE_THREAD_LOCALE) 获取转换以使用 CP_ACP(如 .NET)而不是 CP_THREAD_ACP。 有关详细信息,请参阅 _CONVERSION_DONT_USE_THREAD_LOCALE

    另一种方法是使用 pinvoke 调用 GetThreadLocale。 使用返回的 LCID 创建一个 CultureInfo。 然后,使用 CultureInfo.TextInfo 获取要在转换中使用的代码页。

    ATL 和 MFC 字符串转换宏
    与 C 样式字符串相关的 CString 操作
    如何:将标准 String 转换为 System::String
    如何:将 System::String 转换为标准 String
    如何:将 System::String 转换为 wchar_t*char*
    使用 CComBSTR 进行编程
    mbstowcs_s, _mbstowcs_s_l
    wcstombs_s, _wcstombs_s_l
    strcpy_s, wcscpy_s, _mbscpy_s
    strcat_s, wcscat_s, _mbscat_s
    pin_ptr (C++/CLI)