将 C# 数组传递给 C++ 方法
Pass a c# array to a c++ method
我有一个 C++ 中的 CLR class 库:
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);
};
}
我正在使用这个 class 作为 WPF 项目中的参考:
ANN_FF_BP neuralNetwork = new ANN_FF_BP(neurons, inputs, outputs);
现在我想从 class 调用 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++ class 库方法吗?
由于您的 ANN_FF_BP
是 ref class
,因此是 CLR
类型,因此最好将 .NET
数组传递给 C++/CLI
方法并执行 努力那里。这样你就不必将你的 C#
代码声明为 unsafe
如果你在 C#
.
中使用指针,那么这里是必需的
这应该有效:
*.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
:
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.
如果您想知道不安全 C# 中的解决方案看起来如何:
unsafe{
fixed(double* ptr1 = &P[0,0])
fixed(double* ptr2 = &T[0])
{
neuralNetwork.Train(ptr1, ptr2, 3, 20, 0.01);
}
}
我有一个 C++ 中的 CLR class 库:
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);
};
}
我正在使用这个 class 作为 WPF 项目中的参考:
ANN_FF_BP neuralNetwork = new ANN_FF_BP(neurons, inputs, outputs);
现在我想从 class 调用 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++ class 库方法吗?
由于您的 ANN_FF_BP
是 ref class
,因此是 CLR
类型,因此最好将 .NET
数组传递给 C++/CLI
方法并执行 努力那里。这样你就不必将你的 C#
代码声明为 unsafe
如果你在 C#
.
这应该有效:
*.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
:
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.
如果您想知道不安全 C# 中的解决方案看起来如何:
unsafe{
fixed(double* ptr1 = &P[0,0])
fixed(double* ptr2 = &T[0])
{
neuralNetwork.Train(ptr1, ptr2, 3, 20, 0.01);
}
}