Pass a c# array to a c++ method

时间秒杀一切 提交于 2021-02-08 04:10:46

问题


I have a CLR class library in c++:

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

I am using this class as a reference in a WPF project:

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

Now I want to call the Train() method (in WPF) from that class and pass in some arguments. I have a problem to pass the first two parameters (pointers) to the method. My current code in 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);

I get the following error in C#:

enter image description here

Can anybody explain me how to pass an C# array to a c++ class library method?


回答1:


As your ANN_FF_BP is a ref class and thus a CLR type it's better to pass .NET arrays to the C++/CLI method and do the hardwork there. This way you don't have to declare your C# code as unsafe what would be necessary here if you used pointers in C#.

This should work:

*.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);
}

To protect the arrays from being moved around in memory by the garbage-collector you need to use the pin_ptr:

A pinning pointer is an interior pointer that prevents the object pointed to from moving on the garbage-collected heap. That is, the value of a pinning pointer is not changed by the common language runtime. This is required when you pass the address of a managed class to an unmanaged function so that the address will not change unexpectedly during resolution of the unmanaged function call.




回答2:


If you wonder how the solution in unsafe C# looks:

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


来源:https://stackoverflow.com/questions/27730017/pass-a-c-sharp-array-to-a-c-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!