Konvertierung System::String => char* oder wchar_t*



  • Es gibt mehrere Möglichkeiten dies zu tun, der "einfachst" ist aber eine Hilfsklasse (struct) zu verwenden, der sich um das Freigeben von Speicher automatisch kümmert:

    #include <windows.h>
    #include <tchar.h>
    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
    

    Die Verwendung ist dann z.b: wie folgt:

    #include <stdio.h>
    int _tmain()
    {
      String ^s = "abc";
      printf("%s", (LPCSTR) StringConvA(s));
      wprintf(L"%s", (LPCWSTR) StringConvW(s));
      _tprintf(_T("%s"), (LPCTSTR) StringConvT(s));
      return 0;
    }
    

    Oder für std::string/wstring:

    #include <string>
    int _tmain()
    {
      String ^s = "abc";
      std::string ansi = StringConvA(s);
      std::wstring unicode = StringConvW(s);
    }
    

    Will man nur nach "const wchar_t" umwandeln, dann kann man auch folgendes verwenden. Dabei wird dann keine kopie des Strings erstellt, sondern direkt auf den Native-Speicher zugegriffen!

    #include <stdio.h>
    #include <vcclr.h> 
    int _tmain()
    {
      String ^s = "abc";
      pin_ptr<const wchar_t> szStr = PtrToStringChars(s); 
      wprintf(L"%s", szStr);
    }
    

    Wer MFC verwendet kann es auch ganz einfach machen:

    CString str(managedString);
    


  • Ab VC2008 gibt es von VC++ Team eine "marshal_as" Library, die im wesentlichen das Konvertieren von Strings vornimmt.
    Siehe dazu auch:
    marshal_as library in VC2008

    Die Verwendung ist simpel:

    #include <string>
    #include <tchar.h>
    #include <msclr/marshal.h>
    #include <msclr\marshal_cppstd.h>
    using namespace System;
    using namespace msclr::interop;
    
    int main(array<String ^> ^args)
    {
      // TO String^
      String ^s1 = marshal_as<System::String^>("Hello world");
      Console::WriteLine(s1);
    
      String ^s2 = marshal_as<System::String^>(L"Hello world");
      Console::WriteLine(s2);
    
      String ^s3 = marshal_as<System::String^>(_T("Hello world"));
      Console::WriteLine(s3);
    
      String ^s = "Hello world";
    
      // FROM String^
      std::string us1 = marshal_as<std::string>(s);
      printf(us1.c_str());
    
      std::wstring us2 = marshal_as<std::wstring>(s);
      wprintf(us2.c_str());
    
      msclr::interop::marshal_context c;  // Context kann wiederverwendet werden!
    
      const char *us3 = c.marshal_as<const char*>(s);
      printf(us3);
    
      const wchar_t *us4 = c.marshal_as<const wchar_t*>(s);
      wprintf(us4);
    
      LPCTSTR us5 = c.marshal_as<LPCTSTR>(s);
      _tprintf(us5);
    }