从托管代码调用C代码

时间:2010-10-23 02:59:04

标签: c# c++-cli interop pinvoke

我目前有一个C函数,我想在.NET(C#)中使用。

我可以看到实现这个目标的两种方法:

  1. 在VC ++ .NET上用/ clr编译它(我认为这是可能的),实现了调用C代码的“façade”托管方法。

  2. 将C代码编译为DLL,然后进行API调用。

  3. 你觉得最好的是什么?如何做第一个?

    更新

    根据要求,这是我需要从托管代码调用的(唯一)函数:

    int new_game(double* params1, double* params2);
    

    还有一个问题(虽然更难)

    我有一个表格

    的功能
    int my_hard_to_interop_function(double** input, double **output, int width);
    

    其中输入和输出都是2D双数组。它们的宽度由width给出,它们的高度由函数知道。我应该从我的C#应用​​程序中调用这个C方法。

3 个答案:

答案 0 :(得分:3)

如果这是一个简单的C API,那么访问它的最直接的方法是使用PInvoke。 PInvoke就是针对这种情况而设计的。

你能发布C方法的签名吗?如果是这样,我们可以提供适当的托管签名。

编辑

[DllImport("insert_the_dll_name_here")]
public static extern int new_game(ref double param1, ref double param2);

汉斯指出,鉴于参数的复数名称,似乎可能是数组与单值。如果是这样,那么签名将需要改变以解决该问题。例如,如果预期它们是预定的固定大小,则签名将如下所示

[DllImportAttribute("insert_the_dll_name_here"]
public static extern int M1(
  [MarshalAsAttribute(UnmanagedType.LPArray, ArraySubType=UnmanagedType.R8, SizeConst=5)] 
  double[] params1),
  [MarshalAsAttribute(UnmanagedType.LPArray, ArraySubType=UnmanagedType.R8, SizeConst=5)] 
  double[] params2) ;

答案 1 :(得分:1)

正如JaredPar所说,这是最简单的方法 - 实际上是设计的方法。

具体来说,您需要使用选项2,并且需要从可执行文件中访问.dll(路径方式)。

答案 2 :(得分:1)

由于您需要在主C#程序的单独DLL中部署C函数,所以使用C ++ / CLI是最简单的。

你有C函数的源代码吗?如果是这样,您可以轻松地将它们转换为ref class的静态成员函数。然后,您可以使用/clr:safe选项并拥有纯托管代码。

如果您没有源代码,或者本机代码无法轻松运行(例如,使用大量C运行时库函数),那么您可以在调用它时构建包装器或外观。托管包装器和本机C代码将在DLL中结束,这使得部署更容易,因为不涉及本机DLL搜索路径。