views:

405

answers:

2

How to marshal the type of "Cstring" in .NET Compact Framework(C#)?

DLLname:Test_Cstring.dll(OS is WinCE 5.0),source code:

extern "C" __declspec(dllexport) int GetStringLen(CString str)
{ 
   return str.GetLength();
}

I marshal that in .NET Compact Framework(C#),for example:

[DllImport("Test_Cstring.dll", EntryPoint = "GetStringLen", SetLastError = true)]
public extern static int GetStringLen(string s);

private void Test_Cstring()
{
   int len=-1;
   len=GetStringLen("abcd");
   MessageBox.Show("Length:"+len.ToString()); //result is -1,so PInvoke is unsuccessful!
}

The Method of "GetStringLen" in .NET CF is unsuccessful! How to marshal this type of "Cstring"? Any information about it would be very appreciated!

+2  A: 

You can't marshal CString as it's not a native type - it's a C++ class that wraps up a char array.

You can marshal string to char[] as char[] is a native type. You need to have the parameters to the function you want to P/Invoke into as basic types like int, bool, char or struct, but not classes. Read more here:

http://msdn.microsoft.com/en-us/library/aa446536.aspx

In order to call functions that take CString as an argument you can do something like this:

//Compile with /UNICODE
extern "C" MFCINTEROP_API int GetStringLen(const TCHAR* str) {
  CString s(str);
  return s.GetLength();
  //Or call some other function taking CString as an argument
  //return CallOtherFunction(s);
}

[DllImport("YourDLL.dll", CharSet=CharSet.Unicode)]
public extern static int GetStringLen(string param);        

In the above P/Invoke function we pass in a System.String which can marshal to char*/wchar_t*. The unmanaged function then creates a instance of CString and works with that.

By default System.String is marshalled to char*, so be careful with what kind of string the unmanaged version takes. This version uses TCHAR, which becomes wchar_t when compiled with /UNICODE. That's why you need to specify CharSet=CharSet.Unicode in the DllImport attribute.

Igor Zevaka
Thanks a lot!I have a Dll with nonsource-code,the dll's head file isgive the type of "Cstring" in dllexport-table.Now I have no option but to wrap this Dll in C++(MFC static-Dll)??
Smart_Joe
A: 

you should do the following:

extern "C" __declspec(dllexport) int GetStringLen(LPCTSTR  str)
{ 
   CString s(str);
   return s.GetLength();
}

The CString is actually an MFC type not a native type. Just grab the string and turn it into a CString in native method.

Preet Sangha
Thanks a lot!I have a Dll with nonsource-code,the dll's head file isgive the type of "Cstring" in dllexport-table.Now I have no option but to wrap this Dll in C++(MFC static-Dll) again??
Smart_Joe