初めて質問させて頂きます。
Windows XP VC++6.0 SP6 の環境で
VBで使用するOLEコントロールを作っています。
(ちなみに今回初めてOLEコントロールを作成しています)
今作ってるOLEコントロールはお客様に提供して頂いたdllを使って
ある機器と通信を行うものです。
実際に提供して頂いたdllのファイルは
AAA.h、AAA.lib、AAA.dll
の3つのファイルのみでセキュリティの都合で
AAA.dllのソース一式は頂く事が出来ない状況です。
今までは、静的リンクでAAA.dllを使用していたのですが
静的リンクですと私が作ったtest.ocxと同じ場所に
AAA.dllがないと動かすこともregsvr32.exeを使って
レジストリ登録することもできません。
先日、お客様より
「AAA.dllがなくてもレジストリ登録できるようにして欲しい」
と言われて動的リンクを調べたのですが、
AAA.dllが関数で構成されていれば
LoadLibrary()
GetProcAddress()
等で問題なく動的リンクに切り替えて実装できると思うのですが
AAA.dllはクラスで構成されていてそのクラスのメソッドを使って
通信を行っているため上記の方法では無理だろうと思っています。
ネットで検索し見つけた唯一、動的リンクが出来そうな方法は
「dll側でクラスをnewしてもらいそのポインタを渡す関数を用意する」
ですが、私の方からはdllの中身を見ることも修正することも出来ない状況です。
AAA.hにはクラスの定義があるだけで、グローバル関数の定義はありません。
お客様曰く、
「レジストリ登録さえできればOLEコントロール自体は動かなくてもいい」
との事です。
最終的には私の作ったOLEコントロールの他にも
いくつかOLEコントロールが登録されているアプリをVBで作成し、
状況によって使用するOLEコントロールを切り替える為、
私の作ったOLEコントロールはインストールはするけれど必ず使用するものではありませ
ん。
更に補足しますと私の作ったOLEコントロールは別のツールをインストールしないと
使えないものです。
(そのツールの中にAAA.dllが含まれています)
ですので、ツールをインストールしていなくてもVBで作ったアプリが
インストールできるようにするために
「AAA.dllがなくてもレジストリ登録できるようにして欲しい」
と言われています。
ネットで調べた私の結論は
どうしても動的リンクしたいのならばAAA.dllに修正を加えて貰うしかない。
(dll側でクラスをnewしてもらいそのポインタを渡す関数を追加してもらう。
それでも100%解決できるかは保障できませんが・・・)
それが駄目なら現状の静的リンクでお客様の方でAAA.dllに関しては
インストール時になんとか対応して頂くしかない。
なのですが、他に解決策はありますでしょうか?
今まで静的リンクでしかdllを使用したことがないので
動的リンクの知識がありません・・・
長文な上に曖昧な説明で申し訳ありませんが
アドバイス等ありましたら教えて下さい、宜しくお願い致します。
こんな感じで逃げられませんか。
OLEコントロールからは、一度別のプロキシDLL(newをするI/Fを持つ)を動的に参照する。
AAA.dllを用いたプロキシDLLを用意する。AAA.dllを用いないスタブDLLも用意してもよい。
AAA.dllと性的リンクして直接依存するのは、上記プロキシDLLとする。
> AAA.dllと性的リンクして直接依存するのは、上記プロキシDLLとする。
AAA.dllと静的リンクして直接依存するのは、上記プロキシDLLとする。
> AAA.dllと性的リンクして直接依存するのは、上記プロキシDLLとする。
AAA.dllと静的リンクして直接依存するのは、上記プロキシDLLとする。
DLLを遅延読み込み(/delayloadオプション)させてみてはどうでしょうか?
# 二重書き込みになってました…orz
Ban様、subaru様 回答有難う御座います。
>Ban様
逃げられませんでした・・・。
素晴らしい提案だと思ったのですが、上司に相談してみたら
間に新しいDLLを中継させるのはお客様が納得しないだろうとのことです。
>subaru様
遅延読込みを早速試して上手く行く事まで確認できたのですが、
VBアプリ作成者に確認したところOLEコントロールは使用しない場合でも
画面上には常に張り付いているらしくそうなると結局DLLがない状態でも
私の作ったOLEコントロールが起動されることになり、
DLLがないことによりアプリが強制終了して駄目だという事になってしまいました。
良いアドバイスを頂いたのですが結局、お客様に動的リンクは無理と相談する事に
なりそうです。
しかし、いろんな考えを教えて頂き大変勉強になりました。
本当に有難うございます。
また、質問することがありましたら宜しくお願いします。
Banさんの方法が現実的な気がしますね。
早い話が、問題のDLLを静的にリンクして内部でクラスインスタンスを作成して
関数呼び出しをするようなDLL(B)を作成し、このDLL(B)は機能を関数でexportしておく。
こうしておけば、OCX側はDLL(B)を動的にロードする事で機能の呼び出しができるので
OCXの登録時は多分問題ない。
但し、AAA.dllが無いとDLL(B)は使えないのでAAA.dllが無い状態でOCXを使おうとすると
動かない。
がーん、時間差の上に間に合わなかった。
間に挟むのは駄目と言うのは、不具合が起こった時の切り分けが面倒になるからかな。
本来ならどうしても動的なリンクがしたいならAAA.dllに関数でのexportも追加実装するのが
一番現実的でしょうねぇ。
本来、本物の AAA.dll があるべきところに、
自分で作った偽物を置いておくのも駄目ですかね。