代码之家  ›  专栏  ›  技术社区  ›  Mark T

从C++中获取非托管C++函数

  •  4
  • Mark T  · 技术社区  · 15 年前

    我可以做一些偶然的改变,比如从.c到.cp文件名的改变,以便它使用Visual Studio 2009的C++编译器编译,我已经完成了。还可以添加编译器指令等。如有必要,我还可以遍历包装层。

    不安全的 任何C#代码中的关键字。

    我需要从C#程序中获取这些函数。


    double SomeFunction(double a, double[3] vec, double[3][3] mat);
    数组内容有时是输入的,有时是输出的,很少两者都是。

    然后我尝试了两个项目在同一个解决方案中,一个在C++中,另一个在C语言中。在C++项目中,我创建了一个托管函数,它只是调用了被标记为非托管的原始函数。这是非常干净和简单的,同样,简单的论点很好。但是对于数组,我找不到如何使参数类型匹配C跨到C++边界:
    Argument '2': cannot convert from 'double[]' to 'double*'
    (如上所述,我不能使用unsafe来获取指针)。

    当然,我想做的一定是可能的。

    3 回复  |  直到 15 年前
        1
  •  4
  •   Hans Passant    15 年前

    C/C++实现示例:

    extern "C" __declspec(dllexport)
    double SomeFunction(double a, double vec[3], double mat[3][3]) {
      double sum = a;
      for (int ix = 0; ix < 3; ++ix) {
        sum += vec[ix];
        for (int iy = 0; iy < 3; ++iy) {
          sum += mat[ix][iy];
        }
      }
      return sum;
    }
    

    private void Form1_Load(object sender, EventArgs e) {
      double[] vec = new double[3];
      double[,] mat = new double[3, 3];
      for (int ix = 0; ix < 3; ++ix) {
        vec[ix] = ix;
        for (int iy = 0; iy < 3; ++iy) {
          mat[ix, iy] = (ix + 1) * iy;
        }
      }
      double sum = SomeFunction(1, vec, mat);
    }
    [System.Runtime.InteropServices.DllImport("cpptemp8.dll")]
    private static extern double SomeFunction(double a, double[] vec, double[,] mat);
    
        2
  •  1
  •   Andy    15 年前

    如果无法使extern和P/Invoke解决方案正常工作,那么包装器可能是最佳选择。创建一个使用托管和非托管代码的托管C++ DLL。将一个.NET类添加到此DLL中,该类只是C DLL中函数的薄包装。您的C代码可以调用C++ .NET类,它将依次转发C函数。

    通过这种方式,您可以自己编写.NET和非托管代码之间的转换,而不是依赖运行时来完成。

        3
  •  0
  •   patrick    15 年前