ghet
ghet

Reputation: 145

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.

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#?

Upvotes: 6

Views: 931

Answers (3)

David Heffernan
David Heffernan

Reputation: 612993

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.

Upvotes: 3

Emond
Emond

Reputation: 50672

A very useful site with tooling and lots of good information is http://pinvoke.net/

It might help you.

Upvotes: 1

ukhardy
ukhardy

Reputation: 2104

C++

void GetString( char* buffer, int* bufferSize ); 

C#

int bufferSize = 512; 
StringBuilder buffer = new StringBuilder( bufferSize ); 
GetString( buffer, ref bufferSize )

Upvotes: 0

Related Questions