Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# calling native C++ all functions: what types to use?

I want to make a native C++ all that can be used from a C# project.

  • If I want to pass a string from C# to the function in the C++ all, what parameter should I use?
  • I know that C# strings use Unicode, so I tried wchar_t * for the function but it didn't work; I tried catching any exceptions raised from the called function, but no exception was thrown.
  • I also want to return a string so I can test it.

The C++ function is the following:

DECLDIR wchar_t * setText(wchar_t * allText) {
  return allText;
}

The C# code is the following:

[DllImport("firstDLL.Dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]     
public static extern string setText(string allText);

var allText= new string('c',4);
try {
  var str1 = setText(allText);
}
catch (Exception ex) {
  var str2 = ex.Message;
}

What type should I use for the C++ function's return type, so that I can call it from C# with a return type of string[]? the same Q but for the parameter of the function to be string[] in C#?

like image 251
ghet Avatar asked Mar 20 '11 13:03

ghet


1 Answers

I'd probably do it with a COM BSTR and avoid having to mess with buffer allocation. Something like this:

C++

#include <comutil.h>
DECLDIR BSTR * setText(wchar_t * allText)
{
    return ::SysAllocString(allText);
}

C#

[DllImport(@"firstDLL.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
private static extern string setText(string allText);

BSTR is the native COM string type. The advantage of using it here is that the memory can be allocated on the native side of the interface (in C++) with the COM allocator, and then destroyed on the managed side of the interface with the same allocator. The P/Invoke marshaller knows all about BSTR and handles everything for you.

Whilst you can solve this problem by passing around buffer lengths, it results in rather messy code, which is why I have a preference for BSTR.


For your second question, about P/Invoking string[], I think you'll find what you need from Chris Taylor's answer to another question here on Stack Overflow.

like image 105
David Heffernan Avatar answered Oct 06 '22 00:10

David Heffernan