2011-01-10 4 views
9

私は、Excel VBAから自分のC++ DLL関数を呼び出すしたいと思います:Excel VBAからC++へのポインタへの参照を渡すことはできますか?

void my_cpp_fun (int& n_size, double*& my_array); 

C++関数は、可変サイズn_sizeの配列my_arrayでを作成します(このサイズはmy_cpp_fun内で計算されます)。

C++コードでExcel固有のものを使用せずに、この関数をVBAと同じようにインターフェイスすることはできますか?私は新しいを使用してC++のdll内のメモリを割り当てる場合は、そのメモリは一度利用できるようになります:だから基本的に私が探していますが

Declare Sub my_cpp_fun Lib "my_cpp.dll" (n_size As Long, Ref_to_Ptr_Qualifier my_array As Double) 

ちょうど私に発生した別の問題のようなVBAのDeclareステートメントである

DLL関数はVBに制御を返しますか?それ以外の場合は、上記無意味です...

答えて

6

短い答えを使用して、VBAでそれをロードする必要があるだろう:はい、そうですVBAからDLL内の関数を呼び出すことが可能です(COMルートよりも簡単です)。私の経験上、最良の方法は、Cリンケージ(さまざまなC++ネームマングリングスキームへの実行を避けるため)とラッパー関数を作成し、参照ではなくポインターのインターフェースを公開することです(参照引数を宣言するための適切なVBAタイプとして結果は予測するのがむしろ難しいでしょう)。

適切なDeclareステートメント(32ビットWindowsを想定)を書く方法の素晴らしいガイドは、「ハードコアVisual Basic」の第2章です。

Declareステートメントを介してVBAに公開される関数は、stdcall(別名WINAPI)呼び出し規約を使用する必要があることにも注意してください。

TLDR:

 
extern 'C' { 
    void WINAPI my_cpp_fun_wrapper (int *n_size, double **my_array) 
    { 
     my_cpp_fun(*n_size, *my_array); 
    } 
} 

、その後

Declare Sub my_cpp_fun_wrapper Lib "my_cpp.dll" (ptr_n_size As Long, ptr_ptr_my_array As Long)

、私へのポインタを取得するにはVB6/VBAのさまざまな*Ptr機能を使用します。

私はこれを行うだろうデータ。

1

あなたの機能を公開するCOMオブジェクトを作成し、CreateObject

+1

は、だから、私は – Hans

+0

(n_sizeロング、ダブルとしてMagic_Ref_to_ptr_qualifierのmy_arrayで同様)サブmy_cpp_fun Libの「my_cpp.dll」を宣言し のような単純なものを考えていた?ExcelのAPIを使用せずには不可能であることは可能であるが、それは方法ですそのルートに行く価値よりも多くのトラブル。 VBとのインターフェイスをとるときに、COM DLLが未処理のDLLをラップするのははるかに簡単です。 –

+3

いいえ、インターフェイスの表面積が小さい場合、COMよりも宣言が簡単です。 COMは、特にC++の裏側にある王様の痛みです。 –