且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

的P / Invoke从C#调用C DLL

更新时间:2021-11-02 23:30:51

所有code首先是C ++而不是C.你的函数接收类型的std ::字符串和使用的std ::字符串意味着你code实际上是C ++。

First of all your code is C++ rather than C. Your function receives a parameter of type std::string and the use of std::string means that your code is actually C++.

现在这个参数的类型是你的问题的根源。你不能在.NET中创建一个的std ::字符串,而是需要使用一个的char * 来传递字符串数据。下面code是你所需要的:

Now this parameter type is the root of your problem. You cannot create a std::string in .net and instead will need to use a char* to pass the string data. The following code is what you need:

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

默认的P / Invoke的.NET 字符串编组是通过一个的char * [IN] 参数。没有必要为的IntPtr StringToHGlobalAnsi FreeHGlobal $ C $的复杂性C>通过其他的答案之一,建议。如果你可以让的P / Invoke封送处理做的工作那么它是preferable这样做。

The default p/invoke marshalling for a .net string is to pass a char* as an [In] parameter. There is no need for the complexity of IntPtr, StringToHGlobalAnsi, FreeHGlobal as suggested by one of the other answers. If you can let the p/invoke marshaller do the work then it is preferable to do so.

请注意,您还需要确保您的调用约定相匹配。根据该建立你的C ++ code,当你没有使用任何特殊的编译器选项的假设,即code将默认使用 CDECL 调用约定。您可以进行匹配与 CallingConvention 参数设置为的DllImport 属性。

Note that you also need to make sure that your calling conventions match. Under the assumption that you have not used any special compiler options when building your C++ code, that code will default to used cdecl calling convention. You can make that match with the CallingConvention parameter to the DllImport attribute.