开发者

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

开发者 https://www.devze.com 2023-02-17 19:21 出处:网络
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 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 fun开发者_运维问答ction 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#?


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.


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

It might help you.


C++

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

C#

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号