- ベストアンサー
VBからDLLへ多次元配列を渡す/配列の添え字
C++で作ったdllにVBAから配列を渡して、計算結果を再びVBAに戻して、アウトプットはVBAで、ということをしています。(経験豊富な方への相談です。) 具体的には、渡したい配列の先頭アドレスをlong型で記憶し、そのlong型の配列を受け渡ししています。 ただ、ご存知の方が多いかもしれませんが、VBAとC++では配列の添え字の順序が逆になっており、非常に面倒です。どういうことかといいますと、 Dim array(0 to 4, 0 to 9) as long をdllに渡し、array(2,6)を参照したい場合、C++では(Cでの配列名をc_arrayとし、これに先頭アドレスを入れると)、 c_array[(4+1)*6 + 2 ]; としなければならないと思います。これをプリプロセッサで #define C_ARRAY(a,b) c_array[(4+1)*b + a] としたらVBでの配列の感覚で扱えますが、この擬似配列C_ARRAY(a,b)を関数に渡すときなどは結局同じ混乱が再び生じることになってしまいます。 これを、何らかの方法で、簡潔に解決することはできないものでしょうか? VBA(エクセルを念頭においています)のほうで配列の添え字の順序をC++のそれに沿うように変更できたりしたら非常にうれしいですが、無理でしょうか?
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
SAFEARRAYを使用してマーシャリングを行うという方法があります。 http://www.microsoft.com/japan/msdn/vs_previous/vbasic/docs/dll/#8
その他の回答 (1)
- oldroot2005
- ベストアンサー率66% (68/103)
解決すべき問題が今ひとつ把握できずにいますが。 VBA 側で Private Declare Function func Lib "C:\tmp\Array2D\Array2D___Win32_Debug\Array2D.dll" Alias "_func@4" (ByRef a As Long) As Long ... Dim a(0 To 4, 0 To 9) As Long ... func a(0, 0) のように呼び出した場合、C/C++ 側で、 extern "C" __declspec(dllexport) int __stdcall func(long array[][5]) で受ければ、VB 側の a(2,6) は C/C++ では array[6][2] となるのですが…。 「c_array[(4+1)*6 + 2 ]; としなければならないと思います」と書かれていますが、一次元配列で受けてしまわず、二次元配列で受け取れば、単純に添え字の順序が逆になるだけです。これでは問題の解決になりませんか?
お礼
ありがとうございます。もともと大きな問題ではないのですが、残念ながら問題の解決にはならないと思います。 VBAでコーディングされた計算時間を要するsubroutineを、スピードアップを図るためCでコーディングしてdllとしてVBAから使用する、ということが念頭にあります。ですので(もとのコードがVBで存在するため)CとVBで配列の順序が異なるとコーディングミスの原因となりやすいのです。
お礼
早速の情報どうもありがとうございます。 まだ全部よんでおりませんが、役に立ちそうです。試してみます。 パフォーマンスの低下はある程度ありそうですが、経験的なコメントはありますでしょうか?