UPDATE 6/7/2006
Nishant Sivakumar had a project on
Code Project entitled
StringConvertor which allows the implementer to convert System::String objects to unmanaged char pointers, STL strings, etc in C++/CLI. This is a very handy class to have when dealing with unmanaged code and translating back and forth.
I came across the need for some of these things when working with ISAPI technologies where I wanted to easily go between managed and unmanaged strings. I was only using Visual Studio 2003, and unfortunately, this was only written for Visual Studio 2005 C++/CLI.
So, I decided that I was going to make a few changes here and there to get this to work with Managed C++ or MC++ for short. The first thing I did was turned the class from a managed to an unmanaged class. This was because MC++ does not support exposing unmanaged types in method signatures if I had any the following:
* Base Class
* Virtual Methods
I removed the instances to std::vector and replaced them with an ArrayList. Yes, I know it wasn't the best choice, but for something quick and easy, this was it. I believe the STL has been improved from MC++ to C++/CLI so it made sense there more than it did in my version.
Also, I tried to do better exception handling when it came to using the STL strings such as catching the std::exception should it ever happen (highly doubtful that it ever would), and freeing the HGlobal in a finally block. ArgumentNullExceptions were also thrown should any of the constructors be passed a NULL reference.
Here is an example of the exception handling code:
// Get pointer and check for success
IntPtr ptr = Marshal::StringToHGlobalAnsi(m_String);
if(ptr != IntPtr::Zero)
{
try
{
// Create and return std::string
return std::string((char*)ptr.ToPointer());
} // try
catch(std::exception)
{
// Return empty std::string if exception thrown
return std::string();
} // catch - std::exception
__finally
{
Marshal::FreeHGlobal(ptr);
} // finally
} // if - ptr
return std::string();
Testing the class is really simple and I will show a brief example of just how to do this:
StringUtilities::StringConverter* converter = new StringUtilities::StringConverter(L"Hello World!");
BSTR bstrValue = converter->GetBSTRCopy();
Console::WriteLine(S"BSTR");
Console::WriteLine(bstrValue);
delete converter;
What this code does is call the StringConverter(const __wchar_t* s) constructor. If I had used S"Hello World" as my input to the constructor, it would have called the StringConverter(String* s) overload. Then the code calls the GetBSTRCopy() method which uses the Marshal::StringToBSTR method to convert my string to a BSTR IntPtr.
The files in question are available now at
SaveFile.