我在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#中遇到以下错误:
有人可以解释一下如何将C#数组传递给c ++类库方法吗?
答案 0 :(得分:2)
由于您的ANN_FF_BP
是ref 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);
}
}