Hi Goran!
I need to pass managed String from to C-style APIs. I see I can use
Marshal::String ToXXX functions. Is this the best we have? I understand
this will allocate a new string and create copy of my String. I want to
pass it as constant (LPCWSTR). I don't need allocation and copying,
just the pointer. Can I have it, pretty please?
If you just need an unciode-string, you can use (version for VC2003):
#include <vcclr.h>
const __wchar_t __pin * unmanaged_str = PtrToStringChar s(managed_str);
And use the "unmanaged_ str" pointer.
See also:
http://blog.kalmbachnet.de/?postid=18 http://support.microsoft.com/kb/311259/
In normal C++, we usually have conversion operator or a function to get
it from a string class (string::c_str( ) or CString::operat or LPCTSTR or
_bstr_t::operat or LPCTSTR etc). Is there a similar thing in .NET?
For conversion you could use the following (version for VC2005):
#include <windows.h>
#include <tchar.h>
#include <string>
using namespace System;
struct StringConvA
{
char *szAnsi;
StringConvA(Sys tem::String ^s)
:
szAnsi(static_c ast<char*>(Syst em::Runtime::In teropServices:: Marshal::String ToHGlobalAnsi(s ).ToPointer()))
{}
~StringConvA()
{
System::Runtime ::InteropServic es::Marshal::Fr eeHGlobal(IntPt r(szAnsi));
}
operator LPCSTR() const
{
return szAnsi;
}
};
struct StringConvW
{
wchar_t *szUnicode;
StringConvW(Sys tem::String^ s)
:
szUnicode(stati c_cast<wchar_t* >(System::Runti me::InteropServ ices::Marshal:: StringToHGlobal Uni(s).ToPointe r()))
{}
~StringConvW()
{
System::Runtime ::InteropServic es::Marshal::Fr eeHGlobal(IntPt r(szUnicode));
}
operator LPCWSTR() const
{
return szUnicode;
}
};
#ifdef _UNICODE
#define StringConvT StringConvW
#else
#define StringConvT StringConvA
#endif
int _tmain()
{
String ^s = "abc";
std::string ansi = StringConvA(s);
std::wstring unicode = StringConvW(s);
_tprintf(_T("%s "), (LPCTSTR) StringConvT(s)) ;
}
Greetings
Jochen