C#调用本机C ++所有函数:要使用哪些类型?

时间:2011-03-20 13:18:03

标签: c# .net c++ windows pinvoke

我想创建一个可以在C#项目中使用的本机C ++。

  • 如果我想将C#中的字符串传递给C ++中的函数,我应该使用什么参数?
  • 我知道C#字符串使用Unicode,所以我尝试了wchar_t *用于该函数,但它没有用;我尝试捕获从被调用函数引发的任何异常,但没有抛出任何异常。
  • 我还想返回一个字符串,以便我可以测试它。

C ++功能如下:

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

C#代码如下:

[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;
}

我应该使用什么类型的C ++函数的返回类型,以便我可以从C#调用它,返回类型为string[]? 相同的Q但是函数的参数是C#中的string []?

3 个答案:

答案 0 :(得分:3)

我可能会使用COM BSTR进行操作,避免混淆缓冲区分配。像这样:

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是本机COM字符串类型。这里使用它的优点是可以使用COM分配器在接口的本机端(在C ++中)分配内存,然后在具有相同分配器的接口的托管端销毁。 P / Invoke marshaller了解BSTR的所有内容,并为您处理所有事情。

虽然你可以通过传递缓冲区长度来解决这个问题,但它会导致相当混乱的代码,这就是我偏爱BSTR的原因。


关于P / Invoking string[]的第二个问题,我想你会在这里找到你需要的Chris Taylor's answer到Stack Overflow上的另一个问题。

答案 1 :(得分:1)

一个非常有用的工具和lots of good information网站是http://pinvoke.net/

它可能对你有帮助。

答案 2 :(得分:0)

C ++

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

C#

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