Skip to content

Commit 760484b

Browse files
TylerMSFTTylerMSFT
authored andcommitted
add info about converting narrow and wide strings
1 parent ee98658 commit 760484b

1 file changed

Lines changed: 25 additions & 4 deletions

File tree

‎docs/text/how-to-convert-between-various-string-types.md‎

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22
description: "Learn more about: How to: Convert Between Various String Types"
33
title: "How to: Convert Between Various String Types"
44
ms.custom: "get-started-article"
5-
ms.date: "02/08/2021"
5+
ms.date: 04/21/2022
66
helpviewer_keywords: ["converting string types", "string conversion [C++]", "strings [C++], converting"]
7-
ms.assetid: e7e4f741-3c82-45f0-b8c0-1e1e343b0e77
87
---
98
# How to: Convert between various string types
109

11-
This topic shows how to convert various Visual C++ string types into other strings. The strings types that are covered include `char *`, `wchar_t*`, [`_bstr_t`](../cpp/bstr-t-class.md), [`CComBSTR`](../atl/reference/ccombstr-class.md), [`CString`](../atl-mfc-shared/using-cstring.md), [`basic_string`](../standard-library/basic-string-class.md), and <xref:System.String?displayProperty=fullName>. In all cases, a copy of the string is made when converted to the new type. Any changes made to the new string will not affect the original string, and vice versa.
10+
This topic shows how to convert various Visual C++ string types into other strings.
1211

13-
## Example: Convert from char *
12+
The strings types that are covered include `char *`, `wchar_t*`, [`_bstr_t`](../cpp/bstr-t-class.md), [`CComBSTR`](../atl/reference/ccombstr-class.md), [`CString`](../atl-mfc-shared/using-cstring.md), [`basic_string`](../standard-library/basic-string-class.md), and <xref:System.String?displayProperty=fullName>.
13+
14+
In all cases, a copy of the string is made when converted to the new type. Any changes made to the new string will not affect the original string, and vice versa.
15+
16+
For more background information about converting narrow and wide strings, see [Background: converting between narrow strings and wide strings](#background-converting-between-narrow-strings-and-wide-strings)
17+
18+
## Example: Convert from `char *`
1419

1520
### Description
1621

@@ -778,6 +783,22 @@ Hello, World! (CStringW)
778783
Hello, World! (basic_string)
779784
```
780785

786+
## Background: converting between narrow and wide strings
787+
788+
When dealing with narrow strings ("C"-style strings) and wide strings ("Unicode" strings), legacy C and Windows apps use code pages rather than Unicode encodings. .NET strings are UTF-16, but ATL's `CStringA` is a narrow string, and the conversion from wide to narrow is performed by the [`WideCharToMultiByte`](/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte) Win32 function. When converting a C-style `CHAR*` (important: a C-style `CHAR*` is a .NET `byte*`) to a string, the opposite Win32 function, [`MultiByteToWideChar](/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar)` is called.
789+
790+
Per the documentation, both functions rely on the Windows concept of a code page, not the .NET concept of a culture. To change the system code page, use the Region setting (**Control Panel** > **Region** > **Administrative** tab > **Change system local**).
791+
792+
On an `en-US` version of Windows, the code page defaults to 1033. If you install a different language of Windows, you'll get a different code page. Or you can change it after the fact using the control panel.
793+
794+
There's a mismatch in the way that `CStringA` performs wide to narrow conversion and the way that `gcnew string(CHAR*)` performs narrow to wide conversion.
795+
796+
`CStringA` passes `CP_THREAD_ACP`, which means to use the current thread code page, to the narrowing conversion method. But `string.ctor(sbyte*)` passes `CP_ACP`, which means to use the current system code page, to the widening conversion method. If the system and thread code pages are out of sync, it can cause round-trip data corruption.
797+
798+
To reconcile this difference, there's a constant definition you can include in your C program to get it to use `CP_ACP` (like .NET) instead of `CP_THREAD_ACP`. For more information, see [_CONVERSION_DONT_USE_THREAD_LOCALE](https://social.msdn.microsoft.com/Forums/vstudio/en-US/f3820781-c418-40bf-8c4f-7250001e5b68/visual-studio-2015-update-1-implicit-string-narrow-wide-conversion-and).
799+
800+
Another approach is to `pinvoke` [`GetThreadLocale`](/windows/win32/api/winnls/nf-winnls-getthreadlocale) and use the returned `LCID` to create a [`CultureInfo`](/dotnet/api/system.globalization.cultureinfo?view=net-6.0), and then use `CultureInfo.TextInfo` to get the code page you can use in the conversion.
801+
781802
## See also
782803

783804
[ATL and MFC String Conversion Macros](../atl/reference/string-conversion-macros.md)\

0 commit comments

Comments
 (0)