【问题标题】:How to pass array of doubles from c# to c++ via DllImport如何通过 DllImport 将双精度数组从 c# 传递到 c++
【发布时间】:2019-12-06 09:48:24
【问题描述】:

我有一个 c++ 函数,其方法签名为

MyMethod(std::vector<double> tissueData, std::vector<double> BGData, std::vector<double> TFData, std::vector<double> colMeans, std::vector<double> colStds, std::vector<double> model)

我希望通过 dllimport 在 c# 中调用这个 c++ 函数。在创建 dll 库时,我已将 c++ 端的函数定义为

extern "C" __declspec(dllexport) int MyMethod(double *tissue, double *bg, double *tf, double *colMeans, double *colStds, double* model);

我计划将一个双精度数组从 c# 端传递给 c++ dll 函数。 但是,我不确定应该如何从 c# 端定义 DllImport,以及在将双数组解析为 dllImport 函数时应该如何转换它?

我读了一些关于编组的文章,但我还是不太明白,我不确定它是否可以在这里应用?

【问题讨论】:

  • 您不能从外部 C++ 代码调用。您需要使用一个函数,该函数接受指向每个数组的第一个元素的指针和每个数组的长度作为参数。
  • 你是什么意思?我没有在c#代码中定义dllimport属性
  • 我很困惑。 std::vector 在问题中的作用是什么?另外,带有double* 的函数,该函数如何知道数组长度?至于pinvoke,使用double[]映射到double*

标签: c# c++ visual-studio dllimport unmanaged


【解决方案1】:

您不能与 C++ 类(例如 std::vector)进行互操作,只能与基本的 C 样式数据类型和指针进行互操作。 (作为旁注)这是微软在发明 COM 时试图解决的问题之一。

为了让它工作,你应该导出一个不同的函数,它接收纯 C 数组及其各自的长度:

C++端

extern "C" __declspec(dllexport) int MyExternMethod(
    double *tissue, int tissueLen, 
    double *bg, int bgLen,
    /* ... the rest ... */
);

// implementation
int MyExternMethod(
    double* tissue, int tissueLen, 
    double* bg, int bgLen,
    /* ... the rest ... */ )
{
    // call your original method from here:

    std::vector<double> tissueData(tissue, tissue + tissueLen);
    std::vector<double> bgData(bg, bg + bgLen);
    /* ... the rest ... */

    return MyMethod(tissueData, bgData, /* ...the rest... */);
}

C# 端的互操作导入将是:

C#端

public static class MyLibMethods
{
    [DllImport("MyLib.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int MyExternMethod(
        double[] tissue, int tissueLen,
        double[] bg, int bgLen,
        /*...the rest...*/
    );
}

你可以像这样在 C# 中调用它:

C#端

public int CallMyExternMethod(double[] tissue, double[] bg, /*... the rest ...*/)
{
    return MyLibMethods.MyExternMethod(
        tissue, tissue.Length,
        bg, bg.Length,
        /*...the rest...*/
    );
}

【讨论】:

  • 我不认为这真的是 COM 背后的主要驱动力,但那是另一回事了。但是,此代码省略了调用约定。 C++ 代码使用 cdecl。
  • 很好的@DavidHeffernan,解决了你提到的两个问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-15
  • 2013-03-05
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 2014-06-11
  • 2019-11-14
相关资源
最近更新 更多