visual studio 2008でVBA用の行列演算のdllを作成する

Pocket

こちらのリンクを参照して、VBAからEigenライブラリを使った行列計算をしてみる。

Eigen/Coreだけインクルードし、以下のように、1で初期化した[1,2]行列Aと[2,1]行列Bを作成する。

[cpp]

MatrixXd A=MatrixXd::Ones(1,2);
MatrixXd B=MatrixXd::Ones(2,1);

[/cpp]

上述のリンクのままなにも頭を使わずに、まず足し算の出力だけは簡単にできた。

次は、行列計算をさせたいので、VBA側からは配列を渡したい。

関数の変数が1つのみの時は、C++側、VBA側とも以下のような記述で、VBA側の入力配列の全ての和を出力させることができた。

[cpp]

double __stdcall Add(double x[])

[/cpp]

VBAのDeclare部分

[vb]

Private Declare Function Add Lib "ExcelLink.dll" (ByRef x As Double) As Double

[/vb]

VBAの出力部分

[vb]
For i = 0 To 5
x(i) = i + x(i)
Next

Debug.Print (Add(x(0)))

[/vb]

ところが、同じ要領で以下のように設定すると、計算出力に0が返ってきてしまう。

[cpp]

double __stdcall Add(double x[], double y[])

[/cpp]

[vb]

Private Declare Function Add Lib "ExcelLink.dll" (ByRef x As Double, ByRef y As Double) As Double

[/vb]

色々思考錯誤したものの全くうまくいかず、あきらめかけていたところ、こちらのリンクを参照にして、なんとか解決できた。

最終的な設定は以下の通り。

[cpp]

double __stdcall Mult(double* x, double* y)

A(0,0)=x[0];
A(0,1)=x[1];
B(0,0)=y[0];
B(1,0)=y[1];

z=A*B;
Map<MatrixXd>(&z2[0],1,1)=z;
z3=z2[0];

return z3;

[/cpp]

[vb]

Private Declare Function Mult Lib "ExcelLink.dll"(ByRef x As Double, ByRef y As Double) As Double

x(0) = 3
x(1) = 5
y(0) = 4
y(1) = 5

Debug.Print (Mult(x(0), y(0)))

[/vb]

上記の設定で、[1,2]行列と[2,1]行列の積を計算し、結果の37を出力させることができた。

cppdllVBA

ただ、このように出力値がスカラー値の場合は、上記の設定で問題ないが、例えば[2,2]行列同士の積のように、出力値が行列になる場合、関数で出力値が1つだけだと表現できない。

出力も配列にするにはどうすればいいんだろう?

また、デバッグする時に、計算途中の値がVBAのローカル画面で確認できるといいんだけど、、、。

まだまだやりたいことを全て達成するには時間がかかりそうだ、、、。

Pocket

コメント

タイトルとURLをコピーしました