private: char* StringToChar(String^ str)
{
char *ch;
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
size_t convertedChars = 0;
size_t sizeInBytes = ((str->Length + 1) * 2);
ch = (char *)malloc(sizeInBytes);
wcstombs_s(&convertedChars, ch, sizeInBytes, wch, sizeInBytes);
return ch;
}
Конвертирование из String^ в Char*
Никак не получается переконвертировать строку из String^ в char*.
В MSDN нашёл несколько способов.
Код:
Эта функция не позволяет конвертировать русские буквы, а для меня конвертирование русских букв - обязательное условие.
Ещё нашёл такую статью:
Цитата:
Method 1
PtrToStringChars gives you an interior pointer to the actual String object. If you pass this pointer to an unmanaged function call, you must first pin the pointer to ensure that the object does not move during an asynchronous garbage collection process:
//#include <vcclr.h>
System::String * str = S"Hello world\n";
const __wchar_t __pin * str1 = PtrToStringChars(str);
wprintf(str1);
Back to the top
Method 2
StringToHGlobalAnsi copies the contents of a managed String object into native heap, and then converts it into American National Standards Institute (ANSI) format on the fly. This method allocates the required native heap memory:
//using namespace System::Runtime::InteropServices;
System::String * str = S"Hello world\n";
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal(str2);
Note In Visual C++ 2005, you must add the common language runtime support compiler option (/clr:oldSyntax) to successfully compile the previous code sample. To add the common language runtime support compiler option, follow these steps:
1. Click Project, and then click ProjectName Properties.
Note ProjectName is a placeholder for the name of the project.
2. Expand Configuration Properties, and then click General.
3. In the right pane, click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project settings.
4. Click Apply, and then click OK.
For more information about common language runtime support compiler options, visit the following Microsoft Developer Network (MSDN) Web site:
http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx (http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx)
These steps apply to the whole article.
Back to the top
Method 3
The VC7 CString class has a constructor that takes a managed String pointer and loads the CString with its contents:
//#include <atlstr.h>
System::String * str = S"Hello world\n";
CString str3(str);
printf(str3);
Back to the top
Complete Sample Code
//compiler option: cl /clr
#include <vcclr.h>
#include <atlstr.h>
#include <stdio.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
int _tmain(void)
{
System::String * str = S"Hello world\n";
//method 1
const __wchar_t __pin * str1 = PtrToStringChars(str);
wprintf(str1);
//method 2
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal(str2);
//method 3
CString str3(str);
wprintf(str3);
return 0;
}
PtrToStringChars gives you an interior pointer to the actual String object. If you pass this pointer to an unmanaged function call, you must first pin the pointer to ensure that the object does not move during an asynchronous garbage collection process:
//#include <vcclr.h>
System::String * str = S"Hello world\n";
const __wchar_t __pin * str1 = PtrToStringChars(str);
wprintf(str1);
Back to the top
Method 2
StringToHGlobalAnsi copies the contents of a managed String object into native heap, and then converts it into American National Standards Institute (ANSI) format on the fly. This method allocates the required native heap memory:
//using namespace System::Runtime::InteropServices;
System::String * str = S"Hello world\n";
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal(str2);
Note In Visual C++ 2005, you must add the common language runtime support compiler option (/clr:oldSyntax) to successfully compile the previous code sample. To add the common language runtime support compiler option, follow these steps:
1. Click Project, and then click ProjectName Properties.
Note ProjectName is a placeholder for the name of the project.
2. Expand Configuration Properties, and then click General.
3. In the right pane, click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project settings.
4. Click Apply, and then click OK.
For more information about common language runtime support compiler options, visit the following Microsoft Developer Network (MSDN) Web site:
http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx (http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx)
These steps apply to the whole article.
Back to the top
Method 3
The VC7 CString class has a constructor that takes a managed String pointer and loads the CString with its contents:
//#include <atlstr.h>
System::String * str = S"Hello world\n";
CString str3(str);
printf(str3);
Back to the top
Complete Sample Code
//compiler option: cl /clr
#include <vcclr.h>
#include <atlstr.h>
#include <stdio.h>
#using <mscorlib.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
int _tmain(void)
{
System::String * str = S"Hello world\n";
//method 1
const __wchar_t __pin * str1 = PtrToStringChars(str);
wprintf(str1);
//method 2
char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal(str2);
//method 3
CString str3(str);
wprintf(str3);
return 0;
}
Но с помощью этих методов у меня всё-равно не получилось.
Может быть кто-нибудь сможет произвести такое конвертирование?
Или может быть как-то изменить первую ф-ю, чтобы она конвертировала русские буквы?
Буду очень благодарен за помощь!
Взял из пример из MSDN - работает.
Код:
// convert_string_to_wchar.cpp
// compile with: /clr
#include < stdio.h >
#include < stdlib.h >
#include < vcclr.h >
using namespace System;
int main() {
String ^str = "Hello";
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
printf_s("%S\n", wch);
// Conversion to char* :
// Can just convert wchar_t* to char* using one of the
// conversion functions such as:
// WideCharToMultiByte()
// wcstombs_s()
// ... etc
size_t convertedChars = 0;
size_t sizeInBytes = ((str->Length + 1) * 2);
errno_t err = 0;
char *ch = (char *)malloc(sizeInBytes);
err = wcstombs_s(&convertedChars,
ch, sizeInBytes,
wch, sizeInBytes);
if (err != 0)
printf_s("wcstombs_s failed!\n");
printf_s("%s\n", ch);
}
// compile with: /clr
#include < stdio.h >
#include < stdlib.h >
#include < vcclr.h >
using namespace System;
int main() {
String ^str = "Hello";
// Pin memory so GC can't move it while native function is called
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
printf_s("%S\n", wch);
// Conversion to char* :
// Can just convert wchar_t* to char* using one of the
// conversion functions such as:
// WideCharToMultiByte()
// wcstombs_s()
// ... etc
size_t convertedChars = 0;
size_t sizeInBytes = ((str->Length + 1) * 2);
errno_t err = 0;
char *ch = (char *)malloc(sizeInBytes);
err = wcstombs_s(&convertedChars,
ch, sizeInBytes,
wch, sizeInBytes);
if (err != 0)
printf_s("wcstombs_s failed!\n");
printf_s("%s\n", ch);
}
Цитата:
Взял из пример из MSDN - работает.
.............................
.............................
.............................
.............................
.............................
.............................
Этот код не конвертирует русские буквы. Я же его и приводил в самом верху.
Я конечно понимаю, что можно использовать драйвер для подключения к MySQL, но в моём случае это будет не самый оптимальный вариант.
Поэтому нужно конвертировать.
Обратно: из char* в String^ у меня получилось.
У МЕНЯ ПОЛУЧИЛОСЬ!!!:D :D :D
Код:
IntPtr ptr = Marshal::StringToHGlobalAnsi(str);
char* char_str = (char*)ptr.ToPointer();
char* char_str = (char*)ptr.ToPointer();
Всё оказалось очень просто.
И русские буквы тоже конвертируются!
:D
Вот ништяк, а я уж сам собрался писать функцию. Спасибо
array<unsigned char>^ arr = System::Text::Encoding::GetEncoding(866)->GetBytes("Cтрока");
Для ANSI:
array<unsigned char>^ arr = System::Text::Encoding::GetEncoding(866)->GetBytes("Cтрока");
А там уже если нужен именно char*, то
pin_ptr<unsigned char> ptr = &arr[0];
char* str = (char*)ptr;
Может побольше кода получается, но System::Text::Encoding::GetEncoding(866)->GetBytes("Cтрока"); на мой взгляд выглядит адекватней нежели
System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi("Строка")