使用するDLL内の関数を任意名称で使用するには?


まさくん  2003-04-26 08:32:00  No: 77827

通常DLL内の関数を使用する場合には「参照設定」でDLLを設定したり、
decalreでDLLファイル名称、関数名称を指定して使用すると思いますが
これを将来、DLLファイル名称、関数名称が変わっても再コンパイル等しなくても
使用する方法はあるのでしょうか?
当然、各名称はiniファイル等で定義できるようにします。あと関数のパラメータ
も変えません。ファイル名称、関数名称だけを任意定義にしたいのです。
どなたかご存じの方が見えましたらお教えください。
お願いいたします。


Loreley  2003-04-26 09:38:26  No: 77828

DLLを自作できるようですので、
中間となるDLLをもうひとつ用意し、
その中間DLLから動的に対象のDLLを呼び出せばいけると思います。

VBだけでの方法は私にはわかりません。


魔界の仮面弁士  2003-04-26 11:58:04  No: 77829

環境は何でしょうか?
一口にVBといっても、VB2〜VB4/16, VB4/32, VB5, VB6, eVB, VB.NET,
VBScript, Office VBA等々ありますが…。

> これを将来、DLLファイル名称、関数名称が変わっても再コンパイル等しなくても
> 使用する方法はあるのでしょうか?

ActiveX DLLの場合は、参照設定をせず、
CreateObject関数で呼ぶようにすれば良いかと思います。

例えば、ProgIdをiniファイル等から得るようにして、
  Set X = CreateObject(strProgID)
  A = X.Proc1()
  B = X.Proc2()
のようなコードにするわけです。
この場合、メソッド名や引数の仕様などといったインターフェイス部は、
各DLL間ですべて同じにしておく必要があります。

もしも、関数名称や引数仕様まで動的に指定した場合は、
VBScriptではEval関数(*1)やExecuteステートメント、
VB6ならCallByName関数を利用する事が可能です。

(*1) Eval関数:
  ちなみにEVal関数は、Access VBAにも存在するのですが、
  VBScriptのEValとは若干動作が違うので、今回の目的に使うのには
  向いてないと思います。

さて。VB4/32, VB5, VBA等の場合ですが———これらの環境では、
関数名を指定して呼び出す事はできませんので、TLBINF32.DLLを使うか、
もしくはOLE系のAPIを直接呼び出すことで、DLLのメソッド等を
呼び出す事になるでしょう。

といっても、この方法だと非常に煩雑な処理になる事が予想されますので、
かわりにWindows Script Controlコンポートネント(*2)を使い、
VBScriptを経由(*3)して処理する方法をとると良いかと思います。

(*2) Windows Script Controlコンポートネント:
  ScriptControlに関しては、下記を参照してください。
  http://www.microsoft.com/japan/msdn/scripting/maininfo.htm

(*3) VBScriptを経由:
  VBScriptの代わりに、JScriptやPerlScriptでも良いですけどね。(^_^;)

一方、ActiveX DLLではなく、Declareして使うタイプのDLLの場合ですが…
残念ながら、DeclareステートメントのLib句が固定表記であるため、
VBではDLL名を動的に変更して呼ぶ事ができません。

LoadLibrary+CallWindowProc(+FreeLibrary)を使うとか、
アセンブラをメモリに書き込んで実行するという強行手段(*3)が
あるにはありますが…あまりマトモな方法ともいえないでしょうね。

(*3) 強行手段:
  下記参照
  http://members.tripod.com/~masapico/doc_FuncPtr.html

ただし、C++等にて「DLLを呼び出すためのDLL」を作成できるのであれば、
この問題を解決できると思います。あるいは、DynaCall(*4)をインストールして、
それをDeclareステートメント代わりに使うという方法もあります。
例えば、DynaCallを使った場合は以下のようなコードが書けます。

FilePath = "C:\Program Files"
With CreateObject("DynamicWrapper")
    .Register "SHLWAPI.DLL", "PathFileExistsA", "i=s", "f=s", "r=l"
    If .PathFileExistsA(FilePath & vbNullChar) = 0 Then
        MsgBox "存在しません:" & FilePath
    Else
        MsgBox "存在します:" & FilePath
    End If
End With

(*4) DynaCall:
  下記を参照の事。
  http://members.tripod.co.jp/IUnknown/WSH/dwhelper/topics/
  http://www.borncity.com/WSHBazaar/WSHDynaCall.htm


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加