From: Paul F. <fle...@gm...> - 2010-09-20 20:57:29
|
Hi I'm wrapping the following C++ code: #include <string> class utf8string { private: string m_utf8string; public: string get() const; void set(const string& value); }; string utf8string::get() const { return m_utf8string; } void utf8string::set(const string& value) { m_utf8string = value; } which stores a UTF8 encoded string. When using SWIG to wrap this for access from .Net I get the following C# code: public string get() { string ret = stringtestPINVOKE.utf8string_get(swigCPtr); return ret; } public void set(string value) { stringtestPINVOKE.utf8string_set(swigCPtr, value); if (stringtestPINVOKE.SWIGPendingException.Pending) throw stringtestPINVOKE.SWIGPendingException.Retrieve(); } and stringtestPINVOKE.cs contains: [DllImport("stringtest", EntryPoint="CSharp_utf8string_get")] public static extern string utf8string_get(HandleRef jarg1); [DllImport("stringtest", EntryPoint="CSharp_utf8string_set")] public static extern void utf8string_set(HandleRef jarg1, string jarg2); Since the C side of these DLL functions specify char* there is an implicit conversion from the .Net Unicode string to char* using the ANSI codepage. I can get around this problem by changing the C# wrapper methods to: public string get() { string ret = System.Text.Encoding.UTF8.GetString(System.Text.Encoding.GetEncoding(1252).GetBytes(stringtestPINVOKE.utf8string_get(swigCPtr))); return ret; } public void set(string value) { stringtestPINVOKE.utf8string_set(swigCPtr, new String(System.Text.Encoding.GetEncoding(1252).GetChars(System.Text.Encoding.UTF8.GetBytes(value)))); if (stringtestPINVOKE.SWIGPendingException.Pending) throw stringtestPINVOKE.SWIGPendingException.Retrieve(); } i.e. explicitly performing the necessary ANSI->UTF8->Unicode/UCS-2 conversions. However, this is code that is auto-generated by SWIG, so my question is am I able to inform SWIG that I want it to use these methods instead? Thanks in advance Paul |
From: William S F. <ws...@fu...> - 2010-09-27 20:04:42
|
Paul Flew wrote: > Hi > > I'm wrapping the following C++ code: > > #include <string> > > class utf8string > { > private: > string m_utf8string; > > public: > string get() const; > void set(const string& value); > }; > > string utf8string::get() const > { > return m_utf8string; > } > > void utf8string::set(const string& value) > { > m_utf8string = value; > } > > which stores a UTF8 encoded string. When using SWIG to wrap this for > access from .Net I get the following C# code: > > public string get() { > string ret = stringtestPINVOKE.utf8string_get(swigCPtr); > return ret; > } > > public void set(string value) { > stringtestPINVOKE.utf8string_set(swigCPtr, value); > if (stringtestPINVOKE.SWIGPendingException.Pending) throw > stringtestPINVOKE.SWIGPendingException.Retrieve(); > } > > and stringtestPINVOKE.cs contains: > > [DllImport("stringtest", EntryPoint="CSharp_utf8string_get")] > public static extern string utf8string_get(HandleRef jarg1); > > [DllImport("stringtest", EntryPoint="CSharp_utf8string_set")] > public static extern void utf8string_set(HandleRef jarg1, string jarg2); > > Since the C side of these DLL functions specify char* there is an > implicit conversion from the .Net Unicode string to char* using the ANSI > codepage. > > I can get around this problem by changing the C# wrapper methods to: > > public string get() { > string ret = > System.Text.Encoding.UTF8.GetString(System.Text.Encoding.GetEncoding(1252).GetBytes(stringtestPINVOKE.utf8string_get(swigCPtr))); > return ret; > } > > public void set(string value) { > stringtestPINVOKE.utf8string_set(swigCPtr, new > String(System.Text.Encoding.GetEncoding(1252).GetChars(System.Text.Encoding.UTF8.GetBytes(value)))); > if (stringtestPINVOKE.SWIGPendingException.Pending) throw > stringtestPINVOKE.SWIGPendingException.Retrieve(); > } > > i.e. explicitly performing the necessary ANSI->UTF8->Unicode/UCS-2 > conversions. > > However, this is code that is auto-generated by SWIG, so my question is > am I able to inform SWIG that I want it to use these methods instead? > Yes, use the csout typemap for changing the string return marshalling in the get() method and csin typemap for changing the string input marshalling in the set method. William |