5

I have a C++ struct

struct UnmanagedStruct
{
   char* s;
};

and a C# struct

struct ManagedStruct {
   string s;
}

How can I marshal the UnmanagedStruct? Do I need to use a StringBuilder?

the C++ library exposes UnmanagedStruct getStruct();

Dexter CD
  • 493
  • 4
  • 13
DevDevDev
  • 5,107
  • 7
  • 55
  • 87

1 Answers1

1

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).

Community
  • 1
  • 1
Sam Harwell
  • 97,721
  • 20
  • 209
  • 280
  • 2
    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 Jul 31 '09 at 23:29
  • I tried that but I keep getting Method's type signature is not PInvoke compatible – DevDevDev Jul 31 '09 at 23:31
  • Reading the Microsoft help it says "ANSI strings must be marshaled using an IntPtr and passed as an array of bytes." – DevDevDev Jul 31 '09 at 23:43
  • @SteveM, what help? Link, please. Most likely it's for some corner case, not applicable here. – Pavel Minaev Aug 01 '09 at 00:13
  • @Pavel here is the link http://msdn.microsoft.com/en-us/library/ms172514.aspx Also I import the DLL like this [DllImport("SomeDLL.dll", CharSet = CharSet.Ansi)] static extern ManagedStruct function( string input ); And inside the DLL the function is extern "C" UnmanagedStruct __declspec(dllexport) function( char* input ); Thanks again for your help. – DevDevDev Aug 03 '09 at 17:46
  • 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 Apr 06 '10 at 23:29