std::string <--> System::String*

J

Jochen Kalmbach [MVP]

Hi Jeff!
This approach was discarded(by me) primarily to avoid the nasty surpises
that go along with implicit conversions, which are the same reasons for
std::string::c_str().

But as a conversion class it should be ok...

By the way, a better defintion should be:


class MarshalNetToStdString {
public:
MarshalNetToStdString(System::String* s) throw(...)
:
cp(static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(s).ToPointer()))
{ }

~MarshalNetToStdString() throw()
{

System::Runtime::InteropServices::Marshal::FreeHGlobal(static_cast<System::IntPtr>(cp));
}

operator const char*() const throw()
{
return cp;
}

private:
char* cp;

MarshalNetToStdString(const MarshalNetToStdString&) throw();
MarshalNetToStdString& operator=(const MarshalNetToStdString&) throw();
};



--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
M

Marcus Kwok

Jochen Kalmbach said:
Hi Jeff!


But as a conversion class it should be ok...

By the way, a better defintion should be:


class MarshalNetToStdString {
public:
MarshalNetToStdString(System::String* s) throw(...)
:
cp(static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(s).ToPointer()))
{ }

~MarshalNetToStdString() throw()
{

System::Runtime::InteropServices::Marshal::FreeHGlobal(static_cast<System::IntPtr>(cp));
}

operator const char*() const throw()
{
return cp;
}

private:
char* cp;

MarshalNetToStdString(const MarshalNetToStdString&) throw();
MarshalNetToStdString& operator=(const MarshalNetToStdString&) throw();
};

I was under the impression that exception specifications were not too
useful[0]. VC++ 6.0 did not handle exception specifications
correctly[1], and as of .NET 2002[2], also did not support them
correctly. MSDN says that VC++ .NET 2003 parses them but does not use
them[3].

[0] http://www.gotw.ca/publications/mill22.htm
[1] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndeepc/html/deep111899.asp
[2] http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndeepc/html/deep08272002.asp
[3] http://msdn.microsoft.com/library/d.../html/vclrf154functionexceptionspecifiers.asp
 
M

Marcus Kwok

Marcus Kwok said:
class MarshalNetToStdString {
public:
MarshalNetToStdString(System::String* s)
: cp(static_cast<char*>(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(s).ToPointer()))
{ }

~MarshalNetToStdString()
{
System::Runtime::InteropServices::Marshal::FreeHGlobal(static_cast<System::IntPtr>(cp));
} [snip]
};

Sorry to come back to this again, but would a __try_cast<> be more
appropriate here than a static_cast<>? Or is my usage of static_cast<>
correct? If I am supposed to use a __try_cast<>, then should I wrap the
destructor body in a try/catch block?
 
T

Tamas Demjen

Marcus said:
Sorry to come back to this again, but would a __try_cast<> be more
appropriate here than a static_cast<>?

You can't do that here. __try_cast<> is a dynamic_cast<> that throws an
exception when the result is 0. You can't dynamic_cast<> from char*, it
has no virtual functions.

Or is my usage of static_cast<> correct?

Yes. In this case you can be sure that char* is convertible to IntPtr,
as it was originally coming from an IntPtr. No one else can change the
value for "cp".

Tom
 
M

Marcus Kwok

Tamas Demjen said:
You can't do that here. __try_cast<> is a dynamic_cast<> that throws an
exception when the result is 0. You can't dynamic_cast<> from char*, it
has no virtual functions.



Yes. In this case you can be sure that char* is convertible to IntPtr,
as it was originally coming from an IntPtr. No one else can change the
value for "cp".

Thanks.
 

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