将c#数组传递给c ++方法

时间:2015-01-01 10:36:27

标签: c# arrays wpf c++-cli class-library

我在c ++中有一个CLR类库:

namespace ANN_Lib {

    public ref class ANN_FF_BP
    {
    private:
        int neurons;
        int inputs;
        int outputs;

        double **wi;
        double *wl;

    public:
        ANN_FF_BP(int neurons, int inputs, int outputs);

        void Train(double **p, double *t, int pairsCount, int epochs, double goal);
    };
}

我在WPF项目中使用此类作为参考:

ANN_FF_BP neuralNetwork = new ANN_FF_BP(neurons, inputs, outputs);

现在我想从该类调用Train()方法(在WPF中)并传入一些参数。我有一个问题是将前两个参数(指针)传递给方法。我目前在C#中的代码:

ANN_FF_BP neuralNetwork = new ANN_FF_BP(neurons, inputs, outputs);
double[,] P = new double[3, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 } };
double[] T = new double[] { 2, 4, 6 };
neuralNetwork.Train(P, T, 3, 20, 0.01);

我在C#中遇到以下错误:

enter image description here

有人可以解释一下如何将C#数组传递给c ++类库方法吗?

2 个答案:

答案 0 :(得分:2)

由于您的ANN_FF_BPref class,因此CLR类型,最好将.NET数组传递给C++/CLI方法并执行辛苦工作那里。这样,如果您在C#中使用了指针,则无需将C#代码声明为unsafe这里需要的内容。

这应该有效:

*.h

void Train(cli::array<double, 2>^ ps, cli::array<double>^ ts, int pairsCount, int epochs, double goal);

*.cpp

void ClrClass::Train(cli::array<double, 2>^ ps, cli::array<double>^ ts, int pairsCount, int epochs, double goal) {

    // pin pointer to first element in ps
    pin_ptr<double> _ps = &ps[0,0];   
    double* p = _ps;

    // pin pointer to first element in ts
    pin_ptr<double> _ts = &ts[0];
    double* t = _ts;

    // Now with the two arrays being pinned you can call you native method.
    NativeClass::Train((double**)p, t, pairsCount, epochs, goal);
}

为了保护数组不被垃圾收集器在内存中移动,您需要使用pin_ptr

  

固定指针是一个内部指针,可防止指向的对象在垃圾收集堆上移动。也就是说,钉钉指针的值不会被公共语言运行库改变。将托管类的地址传递给非托管函数时,这是必需的,这样在解析非托管函数调用期间地址不会意外更改。

答案 1 :(得分:1)

如果您想知道不安全的C#中的解决方案是什么样的:

unsafe{
    fixed(double* ptr1 = &P[0,0])
    fixed(double* ptr2 = &T[0])
    {
        neuralNetwork.Train(ptr1, ptr2, 3, 20, 0.01);
    }
}