p /调用从c#调用C dll

这是我的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); } } 

它成功构建但崩溃如下:

调试http://sofzh.miximages.com/c%23/1qr9sj.jpg

那么,如何使用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]参数传递。 根据其他答案之一的建议, FreeHGlobal IntPtrStringToHGlobalAnsiFreeHGlobal的复杂性。 如果你可以让p / invoke marshaller完成这项工作,那么最好这样做。

请注意,您还需要确保您的呼叫约定匹配。 假设在构建C ++代码时没有使用任何特殊的编译器选项,该代码将默认使用cdecl调用约定。 您可以将CallingConvention参数与DllImport属性匹配。

请查看MSDN上的编组字符串

在坚果shell中,C#字符串不会被编组为std::string而是默认为char*

一方面,返回类型不匹配。 在C中它是void并且在C# int

将您的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); } }