views:

321

answers:

1

I have a C++ struct

struct UnmanagedStruct
{
   char* s;
};

and a C# struct

struct ManagedStruct {
   [MarshalAs(UnmanagedType.LPStr)]
   string s;
}

the C++ library exposes

extern "C" UnmanagedStruct __declspec(dllexport) foo( char* input );

And it is imported like

  [DllImport("SomeDLL.dll", CharSet = CharSet.Ansi)]
  static extern ManagedStruct foo( string input );
A: 

Edit & Correction: For return values of p/invoke calls, the "normal" method doesn't work. I was so used to the normal, ref, and out behaviors related to method parameters that I assumed return values would work in a similar fashion. Here is the link for a solution to the return value problem:
PInvoke error when marshalling struct with a string in it

You only need to use a StringBuilder if you are passing the struct to the C++ method as a byref parameter and the string is a buffer that the method will alter. For a return value, you just need to specify the type of string, which in this case is:

struct ManagedStruct
{
    [MarshalAs(UnmanagedType.Lpstr)]
    string s;
}

Rememer to add a property to expose the string, since s is private here (which is OK, fields should be private).

280Z28
There's nothing wrong with making fields public in structs that are used solely for P/Invoke purposes. All accessors would be trivial anyway, and this would not ever change in the future, so why write more code?
Pavel Minaev
I tried that but I keep gettingMethod's type signature is not PInvoke compatible
DevDevDev
Reading the Microsoft help it says"ANSI strings must be marshaled using an IntPtr and passed as an array of bytes."
DevDevDev
@SteveM, what help? Link, please. Most likely it's for some corner case, not applicable here.
Pavel Minaev
http://msdn.microsoft.com/en-us/library/ms172514.aspx
DevDevDev
@Pavel here is the linkhttp://msdn.microsoft.com/en-us/library/ms172514.aspxAlso I import the DLL like this[DllImport("SomeDLL.dll", CharSet = CharSet.Ansi)]static extern ManagedStruct function( string input );And inside the DLL the function isextern "C" UnmanagedStruct __declspec(dllexport) function( char* input );Thanks again for your help.
DevDevDev
Unless you want ownership of that string passed to C# (letting C# delete it if it likes), UnmanagedType.LPStr is not the right choice. See http://stackoverflow.com/questions/799076 for more details.
Paul Du Bois