Oct 1, 2010

Marshalling string to char* from C# to C++ in .NET

If you are looking for a way how to convert C# string variable to C++ char* variable you probably can't make it without knowing the "magic word" Marshalling. In .NET it's basicly a conversion between an unmanaged and a managed type. If you are calling C++ method from C# program and you want to pass a string as a parameter to this method (for example you have a GUI application written in C# and you want to proccess some user input by algorithm in library written in C++), without any conversion between types, you will get this error
cannot convert from 'System::String ^' to 'char *'
Here comes to scene marshalling. In namespace System.Runtime.InteropServices you can find the class Marshal. You simply add reference to you C++ project.
using namespace System::Runtime::InteropServices;
Then you just get pointer to your parameter using Marshal::StringToHGlobalAnsi. Use static_cast operator to convert the pointer to char* type.
void Adapter::SetSavePath(String^ path)
{
   IntPtr p = Marshal::StringToHGlobalAnsi(path);
   char* newCharStr = static_cast<char*>(p.ToPointer());
}
Then you just call your method in C#.
private void saveAsButton_Click(object sender, EventArgs e)
{
   FolderBrowserDialog fbd = new FolderBrowserDialog();

   if (fbd.ShowDialog() != DialogResult.Cancel)
   {
      if (fbd.SelectedPath != null)
      {
         string savePath = fbd.SelectedPath;
         adapter.SetSavePath(savePath); 
         //adapter is instance of Adapter
      }
   }
}
Easy right? I wish I knew two months ago... It costs me a lot of hair :))

D.Š.