2011-03-20 51 views
6

我想制作一个本地C++,可以从C#项目中使用。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#中的字符串[]?

+1

顺便说一下,当你发现你不知道你的变量是什么类型时,使用这样的var会很快回来咬你。 – 2011-03-20 13:27:45

+0

只要你编译这3个var(s)就成为字符串。 – ukhardy 2011-03-20 13:34:29

+2

@ukhardy哦,来吧,我知道!关键是,当你的代码遍布整个代码时,它比这更复杂,你会发现它是理解现有代码的障碍。 – 2011-03-20 13:56:17

回答

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编组人员知道关于BSTR的所有信息,并为您处理所有事情。

虽然你可以通过传递缓冲区长度来解决这个问题,但是这会导致代码相当混乱,这就是为什么我对BSTR有偏好。


关于第二个问题,关于P /调用string[],我想你会发现你Chris Taylor's answer需要在这里对堆栈溢出的另一个问题是什么。

+0

我真的需要能够处理任何字符,微软字可以这样使用Q:BSTR是否可以保存unicode字符? – ghet 2011-03-20 13:52:40

+0

@ghet BSTR只支持Unicode字符!在我看来,它非常适合您的需求。 – 2011-03-20 13:55:10

+0

至于第二个问:在C++中为返回类型使用什么,以便我可以在c#中有一个字符串[]返回类型,您可以帮助吗? – ghet 2011-03-20 13:57:30

0

C++

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

C#

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

这是一个部分的答案,没有实现没有什么帮助。 – 2011-03-20 13:28:42

+0

P/Invoke编组明确支持零终止的字符串。实现? – ukhardy 2011-03-20 13:45:38

+0

这是真的,但问题是,内容来自外部内存分配器! – 2011-03-20 13:54:18