[英]p/invoke calling C dll from c#
这是我的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);
}
}
它构建成功,但崩溃如下:
那么,如何使用P / invoke从C#调用我自己的C dll? 请帮助,谢谢。
首先,您的代码是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
调用约定。 您可以使用DllImport
属性的CallingConvention
参数使其匹配。
一方面,返回类型不匹配。 在C中为void
,在C#中为int
。
将您的C ++参数类型更改为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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.