C# 从托管代码调用C代码

C# 从托管代码调用C代码,c#,c++-cli,interop,pinvoke,C#,C++ Cli,Interop,Pinvoke,我目前有一个C函数,我想在.NET(C#)中使用 我可以看到实现这一目标的两种方法: 在VC++.NET上使用/clr编译它(我认为这是可能的),实现了调用C代码的“façade”托管方法 将C代码编译为DLL,然后进行API调用 你觉得什么最好?第一个怎么做 更新 根据要求,以下是我需要从托管代码调用的(唯一)函数: int new_game(double* params1, double* params2); 再问一个问题(尽管更难) 我有一个函数的形式 int my_hard_to_in

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

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

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

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

  • 你觉得什么最好?第一个怎么做

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

    int new_game(double* params1, double* params2);
    
    再问一个问题(尽管更难) 我有一个函数的形式

    int my_hard_to_interop_function(double** input, double **output, int width);
    

    其中输入和输出均为二维双数组。其宽度由
    width
    给出,其高度由函数知道。我应该从我的C#应用程序中调用这个C方法。

    如果这是一个简单的C API,那么最直接的访问方法就是使用PInvoke。PInvoke就是为这个场景设计的

    你能把C方法的签名贴出来吗?如果是这样,我们可以提供适当的托管签名

    编辑

    [DllImport("insert_the_dll_name_here")]
    public static extern int new_game(ref double param1, ref double param2);
    
    正如Hans指出的,鉴于参数的复数名称,这些参数可能是数组而不是单个值。如果是这样的话,那么签名将需要更改以说明这一点。例如,如果预期它们是预定的固定大小,则签名将如下所示

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

    正如JaredPar所说,这是最简单的方法——事实上也是设计好的方法


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

    由于您需要将C函数部署在与主C#程序不同的dll中,因此使用C++/CLI是目前为止最简单的方法

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


    如果您没有源代码,或者本机代码无法轻松运行(例如,使用了大量的C运行时库函数),那么您可以构建一个您称之为的包装器或façade。托管包装器和本机C代码最终将一起出现在DLL中,这使得部署更加容易,因为不涉及本机DLL搜索路径。

    我的钱花在这些参数上,它们是数组。注意OP.@Hans中的复数形式,这是一个很好的观点,但是数组没有相应的长度参数似乎很奇怪。也许他们被期望有一个固定的值。我会更新我的答案,要求澄清。