   Problems marshalling C-Style strings to System::Strings in a managed environment
  I''ve been trying to marshal C-Style strings to System::String in a managed environment, but I was unable to do so. I''ve read a lot of documents on this subject during the last few days, and I''m currently able to marshal pointers, arrays, structures, and System::String to C-Style strings, but not the opposite!!!Here''s the code that I''m trying to use to marshal char array to String (It compiles but the System::String object returns random bits of data)   static int Function(int d, System::String __gc **buffer, long size){  IntPtr ptr = Marshal::AllocCoTaskMem(size);  int    ret = ::ibrd(d, (void *)ptr, size);  System::String *temp = Marshal::PtrToStringAnsi(ptr);  *buffer = temp;  Marshal::FreeHGlobal(ptr);  return ret;}I''ve also checked if ptr was bad, and it isn''t, so the problem lies in Marshal:trToStringAnsi();Any help would be greatly appreciated... 
  Why not simply usechar * cstr = "Hi, I''m a c-string!";String * str = new String(cstr);  Regards,Andre;  Thanks man!I was unaware that one of the System::String constructors took a unsigned char *.After all the countless hours I''ve spent reading documents on InteropServices, the solution to my problem was resolved with a simple constructor... GRRR!!! ;  That string constructor expects UNICODE characters, though.My StringHelper class has served me well(just disregard the pool stuff):  // $Id: StringHelper.h 879 2003-09-30 18:32:20Z Arild $#pragma once#include <vcclr.h>#include <svn_utf.h>#include "SvnClientException.h"#include "Pool.h"#include <apr_strings.h>namespace NSvn{    namespace Core    {   using namespace System;   using namespace System::Runtime::InteropServices;   // Helper class to effect string conversions   class StringHelper   {   public:  // <summary>constructor that takes a System::String</summary>  StringHelper( String __gc* string )  { this->string = string; this->charPtr = 0;  }  /// <summary>constructor that takes a const char*</summary>  StringHelper( const char* charPtr )  { this->string = this->ConvertToSystemString( charPtr ); this->charPtr = 0;  }  /// <summary>implicit conversion to a System::String</summary>  operator String*() const  { return this->string;  }  /// <summary>Copy constructor</summary>  StringHelper( const StringHelper& other )  { //System::Strings can be shared this->string = other.string; //char ptrs can not this->charPtr = 0;  }  /// <summary>Assignment operator</summary>  StringHelper& operator=( const StringHelper& other )  { if ( this == &other )return *this; this->string = other.string; if( this->charPtr != 0 )this->FreeCharPtr( this->charPtr ); this->charPtr = 0; return *this;  }  /// <summary>Copies the string to the pool, encoded as UTF8</summary>  char* CopyToPoolUtf8( apr_pool_t* pool )  { const char* utf8String; HandleError( svn_utf_cstring_to_utf8( &utf8String, this->CopyToPool( pool ), pool ) ); return const_cast<char*>(utf8String);  }  char* CopyToPool( apr_pool_t* pool )  { //TODO: unicode issues char* hglobal = this->ConvertToCharPtr( this->string ); //make room in the pool and copy our string there char* ptr = apr_pstrdup( pool, hglobal ); // free the hglobal this->FreeCharPtr( hglobal ); return ptr;  }  /// <summary>implicit conversion to a const char*</summary>  operator const char* () const  { // lazy creation of the char* - we might not need it if ( this->charPtr == 0 )this->charPtr = this->ConvertToCharPtr( this->string ); return this->charPtr;  }  // <summary>dtor - get rid of the char ptr</summary>  ~StringHelper()  { if ( this->charPtr != 0 )this->FreeCharPtr( this->charPtr );  }   private:  /// <summary>convert a char ptr to a System::String</summary>  String __gc* ConvertToSystemString( const char* ptr )  { return Marshal::PtrToStringAnsi( static_cast<IntPtr>(const_cast<char*>(ptr) ) );  }  /// <summary>convert a System::String to a char*</summary>  char* ConvertToCharPtr( String __gc* string ) const  { return static_cast<char*>( Marshal::StringToHGlobalAnsi( string ).ToPointer() );  }  /// <summary>free the memory allocated by the StringToHGlobalAnsi call</summary>  void FreeCharPtr( char* ptr )  { Marshal::FreeHGlobal( static_cast<IntPtr>( static_cast<void*>(ptr) ) );  }  gcroot<String*> string;  mutable char* charPtr;   };    }}Usually I just use it function-style, whenever I need to convert from one of the other: String* someString = S"Moo"; some_c_api( StringHelper(someString) ); or char* ptr = "Foo"; obj->Method( StringHelper(ptr) );. The conversion operators do most of the job. --AnkhSVN - A Visual Studio .NET Addin for the Subversion version control system.[Project site] [Blog] [RSS] [Browse the source] [IRC channel] ;quote:Original post by Arild Fines   That string constructor expects UNICODE characters, though.No, it doesn't. It works with usual ANSI c-strings (0-terminated).http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemStringClassctorTopic3.aspI compiled it and it works. Of course, there *are* c'tors that expect UNICODE. However, that special one I mentioned does not.Regards,Andre   [edited by - VizOne on February 6, 2004 12:49:24 PM];  Weird. My local MSDN(April 2003) says "Initializes a new instance of the String class to the value indicated by a specified pointer to an array of Unicode characters." ;quote:Original post by Arild Fines  Weird. My local MSDN(April 2003) says "Initializes a new instance of the String class to the value indicated by a specified pointer to an array of Unicode characters."   Let me guess: you have the language filter set to C#? In C#, a char* of course is a UNICODE string. But there is a String(sbyte*) construktor which translates to ("real" 8bit) char* in C++. In C++ the original c#-char* constructor parametertype translates to wchar_t *.Weird, isn''t it? :DRegards,Andre ;  D''oh. 