Marshal::StringToXXX question

G

Goran

Hi all!

I need to pass managed String from to C-style APIs. I see I can use
Marshal::StringToXXX 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?

In normal C++, we usually have conversion operator or a function to get
it from a string class (string::c_str() or CString::blush:perator LPCTSTR or
_bstr_t::blush:perator LPCTSTR etc). Is there a similar thing in .NET?

Thanks, Goran.
 
J

Jochen Kalmbach [MVP]

Hi Goran!
I need to pass managed String from to C-style APIs. I see I can use
Marshal::StringToXXX 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 = PtrToStringChars(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::blush:perator LPCTSTR or
_bstr_t::blush:perator 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(System::String ^s)
:
szAnsi(static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(s).ToPointer()))

{}
~StringConvA()
{

System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr(szAnsi));
}
operator LPCSTR() const
{
return szAnsi;
}
};

struct StringConvW
{
wchar_t *szUnicode;
StringConvW(System::String^ s)
:
szUnicode(static_cast<wchar_t*>(System::Runtime::InteropServices::Marshal::StringToHGlobalUni(s).ToPointer()))

{}
~StringConvW()
{

System::Runtime::InteropServices::Marshal::FreeHGlobal(IntPtr(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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top