繁体   English   中英

p /从c#调用C dll

[英]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? 请帮助,谢谢。

请看一下MSDN中的编组字符串

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

首先,您的代码是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]参数。 不需要其他答案之一建议的IntPtrStringToHGlobalAnsiFreeHGlobal的复杂性。 如果可以让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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM