这是我的C代码
extern "C"
{
__declspec(dllexport) void DisplayHelloFromDLL(string a)
{
printf ("%s\n",a)
}
}
这是我的C#代码
class HelloWorld
{
[DllImport("TestLib.dll")]
public static extern void DisplayHelloFromDLL(string a);
static void Main ()
{
string a = "Hello";
DisplayHelloFromDLL(a);
}
}
它构建成功,但崩溃如下:
Debug http://i44.tinypic.com/1qr9sj.jpg
那么,如何使用P / invoke从C#调用我自己的C dll? 请提前帮助,而不是。
答案 0 :(得分:2)
在坚果壳中,C#字符串不会被编组为std::string
,而是默认为char*
答案 1 :(得分:2)
首先,您的代码是C ++而不是C.您的函数接收类型std::string
的参数,使用std::string
意味着您的代码实际上是C ++。
现在,此参数类型是问题的根源。您无法在.net中创建std::string
,而是需要使用char*
来传递字符串数据。您需要以下代码:
<强> C ++ 强>
__declspec(dllexport) void DisplayHelloFromDLL(char* a)
{
printf("%s\n", a);
}
<强> C#强>
[DllImport("TestLib.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void DisplayHelloFromDLL(string a);
static void Main ()
{
string a = "Hello";
DisplayHelloFromDLL(a);
}
.net string
的默认p / invoke编组是将char*
作为[In]
参数传递。根据其他答案之一的建议,不需要IntPtr
,StringToHGlobalAnsi
,FreeHGlobal
的复杂性。如果你可以让p / invoke marshaller完成这项工作,那么最好这样做。
请注意,您还需要确保您的呼叫约定匹配。假设在构建C ++代码时没有使用任何特殊的编译器选项,该代码将默认使用cdecl
调用约定。您可以将CallingConvention
参数与DllImport
属性匹配。
答案 2 :(得分:1)
一方面,返回类型不匹配。在C中,它是void
,在C#int
。
答案 3 :(得分:1)
将您的C ++ param类型更改为char *并按以下步骤更新您的C#代码
class HelloWorld
{
[DllImport("TestLib.dll")]
public static extern void DisplayHelloFromDLL(IntPtr a);
static void Main ()
{
string a = "Hello";
var ptr = System.Runtime.Marshal.StringToHGlobalAnsi(a);
DisplayHelloFromDLL(ptr);
System.Runtime.Marshal.FreeHGlobal(ptr);
}
}