问题
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#:
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