-
January 17th, 2006, 04:40 PM
#1
MC++ & C++/CLI String: How to convert 'System::String' to 'char*'?
Q: How to convert 'System::String' to 'char*' in MC++?
A: There are several methods (notice that the examples are only meant to show how to convert from 'System::String' to 'char*'):
- Using 'PtrToStringChars()'
You can access the wrapped buffer of a 'System::String' using this function, that yields a' __gc' pointer to the first character of a 'System::String' object. If it's passed to a function that expects an unmanaged string ('wchar_t'), it must me pinned first.
- In VC++ 7.x:
Code:
#include <vcclr.h> // required header for PtrToStringChars
size_t GetSize(System::String* str)
{
const wchar_t __pin* unmngStr = PtrToStringChars(str);
return wcslen(unmngStr);
}
size_t size = GetString(S"Method 1");
- In VC++ 8:
Code:
#include <vcclr.h> // required header for PtrToStringChars
size_t GetSize(System::String^ str)
{
pin_ptr<const wchar_t> unmngStr = PtrToStringChars(str);
return wcslen(unmngStr);
}
size_t size = GetString("Method 1");
- Using 'StringToHGlobalAnsi()'
Method 'StringToHGlobalAnsi()' of the Marshal class from the .NET Framework copies the contents of a managed string into unmanaged memory, converting into ANSI format as it copies. Notice, that you'll have to call the 'FreeHGlobal()' method to release the allocated memory.
- In VC++ 7.x:
Code:
using namespace System::Runtime::InteropServices; // for class Marshal
void PrintMessage(System::String* str)
{
TCHAR* str2 = (TCHAR*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal(str2);
}
PrintMessage(S"Method 2");
- In VC++ 8:
Code:
using namespace System::Runtime::InteropServices; // for class Marshal
void PrintMessage(System::String^ str)
{
const char* str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(str);
printf(str2);
Marshal::FreeHGlobal((System::IntPtr)(void*)str2);
}
PrintMessage("Method 2");
- Using 'CString' class.
- In VC++ 7.x, class 'CString' has a special constructor that takes a 'System::String' object:
Code:
#ifdef _MANAGED
// This template will compile only for
// class SystemString == System::String
template<class SystemString>
CStringT( SystemString * pString ) :
CThisSimpleString( StringTraits::GetDefaultManager() )
{
const wchar_t __pin* psz = PtrToStringChars( pString );
*this = psz;
}
#endif
Using this constructor you can write:
Code:
#include <atlstr.h> // for class CString
void Print(System::String* str)
{
CString cstr(str);
printf(cstr);
}
Print(S"Method 3");
- In VC++ 8 (2005) the 'CString' constructor looks like this:
Code:
#if defined(__cplusplus_cli)
template <class SystemString>
CStringT( SystemString^ pString ) :
CThisSimpleString( StringTraits::GetDefaultManager() )
{
cli::pin_ptr<const System::Char> pChar = PtrToStringChars( pString);
const wchar_t *psz = pChar;
*this = psz;
}
#elif defined(_MANAGED)
template <class SystemString>
CStringT( SystemString __gc* pString ) :
CThisSimpleString( StringTraits::GetDefaultManager() )
{
const wchar_t __pin* psz = PtrToStringChars( pString );
*this = psz;
}
#endif
As a result, the previous example changes to:
Code:
#include <atlstr.h> // for class CString
void Print(System::String^ str)
{
CString cstr(str);
wprintf(cstr);
}
Print("Method 3");
Last edited by Andreas Masur; January 19th, 2006 at 05:02 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|