最適化セミナーのご案内

5.1.5 VisualBasicからの呼び出し(VC++)

 ライブラリ部分をDLLにすると一般にVisualBasicなどのアプリケーションから呼ぶことができます.プロジェクトdllは同一のドライバルーチンを使ってDLLを作成するプロジェクトです.

 DLLの入り口となるknapsackSolve()をコールするルーチンを作成すると以下のようになります.このルーチンは入力をknapsackSolveに渡して一度だけ解くという操作を行います.

#include <windows.h>

// nuoptmain()の中でコールする最適化手続き(最適化ライブラリ)
int knapsackSolve(int narg,double* aarg,double barg,double* carg
	     ,double* xarg,double* farg);

// VB から呼ばれる DLL の入り口
#define EXPORT __declspec (dllexport)
#define FORVB _stdcall

extern "C" long EXPORT FORVB nuoptmain(
                       long narg // 問題サイズ
                       ,double* aarg // ベクトル a
                       ,double  barg // ベクトル b
                       ,double* carg // ベクトル c
                       ,double* xarg // ベクトル x(出力)
                       ,double* farg // 目的関数値 (出力)
       ) 
{
  int errCode = knapsackSolve(narg,aarg,barg,carg,xarg,farg); 
  return errCode ;
}

 DLLのデバッグは

  • 出力が得られない
  • 異常が起こると起動アプリごと動作を停止する

など,困難な点が多いので一度ダミーのメイン関数でコールするロードモジュールなどで動作を確認したのち,DLLを作成することをお勧めします.DLLのメインの宣言方法は通常のWindowsアプリケーションと同様です.ここでは,生成したDLLをExcelのVBAからコールする例を示しますのでここではVBAから呼ばれることを前提とした宣言(_stdcall)となっています.まず,DLLを作成しましょう.

 プロジェクト「dll」を選択後,VC++のメニューの「プロジェクト」から「スタートアップ プロジェクトに設定」を選びます.

 次に,「プロジェクト」メニューから「dllのビルド」を選択すると,DLLが作成されます.

 では,これをリンクして実行するVBA側の設定を行います.このDLLを読み込んで実行するサンプルアプリケーションは

(Numerical Optimizerのインストール場所)\samples\appにあるzipファイルを解凍した中にあるdll\dllsample.xls

です.「マクロを有効にする」で,このエクセルファイルを開き,VisualBasicエディタを開くと,Sheet1には次のようなコードが書かれています.これはシートからデータを読み取ってnuoptmainをコールするコードです.下線部はDLLの絶対パスです(先ほどアクティブな構成の設定でデバッグを選択するとこの場所にDLLが作成されます).C++のintはVBAのLong型に,doubleはVBAのDouble型にそれぞれ対応します.

 

 Sheet1に含まれるコード:

Private Sub execbutton_Click()
    ChDir ThisWorkbook.Path
    Dim a() As Double
    Dim c() As Double
    Dim x() As Double
    Dim n As Long
    Dim obj As Double
    n = Range("B2")
    ReDim a(n)
    ReDim c(n)
    ReDim x(n)
    For i = 1 To n
        a(i - 1) = Range("A3").Offset(0, i)
        c(i - 1) = Range("A4").Offset(0, i)
    Next i
    b = Range("B5")
    code = nuoptmain(n, a(0), b, c(0), x(0), obj)
    Range("B7") = code
    Range("B8") = obj
    For i = 1 To n
        Range("A9").Offset(0, i) = x(i - 1)
    Next i
End Sub

 実行させるには,リンクを行う必要があります.サンプルの設定ではExcelブックdllsample.xlsと同じフォルダにあるReleaseフォルダ内に,dll.dllがある場合に正しく動作します.dll.dllの場所を変更する場合は,Module1の下線部を調整します.

 

 DLLの宣言:

 Declare Function nuoptmain Lib "Release\dll.dll" Alias _

 "_nuoptmain@28" (ByVal n As Long, ByRef a As Double, ByVal b As Double , ByRef c As Double, ByRef x As Double, ByRef f As Double) As Long

 

 エクセルシートに戻ってボタンを押すとDLLの実行が行われます.以下はこのコードを使ったアプリケーションの実行例です.


 

 

上に戻る