1

I'm trying to build a wrapper to use cpp code inside c# code, and I want to return custom struct (Class) as output for method2, and std::string for method1, and this is my code in cpp

extern "C" __declspec(dllexport)  std::string method1()
{
  std::string s;
  //Some Code/////////
  return s;
}

and this is the method that should return custom struct (or class)

extern "C" __declspec(dllexport)  MyStruct method2()
{
  MyStruct s;
  //Some Code//////
  return s;
}

and I tried to write c# code for both of these methods and here is my c# code

[DllImport("<dllPath>", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPStr)]
public static extern string  method1(); //Exception

[DllImport("<DllPath>")]
public static extern MyStruct method2(); //Compile Error

Now when I'm trying to run the c# code I get MarshalDirectiveException for method1, and compiling error for method2?

1 Answers1

1

In the first PInvoke, the C++ method should return const char* (s.c_str()). You should remove "[return [...]]" and replace string by IntPtr. Then, you can convert the IntPtr to string with Marshal.PtrToStringAnsi(ptr). http://msdn.microsoft.com/en-US/library/s9ts558h(v=vs.110).aspx can help you.

In the second PInvoke, you should define in C# the MyStruct (but I can't be more precise because I have no information about MyStruct). This link can help you : http://www.codeproject.com/Articles/66243/Marshaling-with-C-Chapter-Marshaling-Compound-Ty

EDIT : Thanks to hvd's comment, it is better sometimes to use BSTR, because the use of char* can be dangerous !

Community
  • 1
  • 1
jd6
  • 429
  • 3
  • 9
  • That's not correct. `s` is a local variable destroyed when the function returns, and the pointer returned by `s.c_str()` stops being valid when `s` is destroyed. Also, this doesn't affect correctness, but why would you return `char *` rather than `const char *`? –  Oct 23 '14 at 09:21
  • You're right ! I made a mistake. I will correct it as soon as possible. I took for example [link](http://stackoverflow.com/questions/370079/pinvoke-for-c-function-that-returns-char), but is it better to use BSTR [link](http://stackoverflow.com/questions/5298268/returning-a-string-from-pinvoke) ? – jd6 Oct 23 '14 at 09:29
  • 1
    That would be a choice the OP should make, not one I should make. :) Returning `char *` may be simpler for some uses, and may be more complicated for other uses. With the limited info in the question, there's no way of knowing which is best. –  Oct 23 '14 at 09:35
  • 1
    Thanks jd6, but this did not work! this is the cpp new code extern "C" __declspec(dllexport) const char *method1() , and this is the c# code [DllImport("", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern IntPtr method1(); but I still get an exception! – M.Hazem Abdullah Oct 23 '14 at 12:00
  • What is the exception ? – jd6 Oct 23 '14 at 15:12