VB掲示板より移動しました。皆様、よろしくお願いします。
>>choro.dll では、単一のDLLのみ静的リンクする様にしたので、AAA.DLLは
>>使っていますが、BBB.DLL〜DDD.DLLは使っていません。AAA.DLLでも
>>BBB.DLL〜DDD.DLLは使っていません。また、AAA.DLLでは、EEE.DLLとFFF.DLL
>>とGGG.DLLを静的リンクしているのですが、これが、表示されていません。
>BBB.DLL〜DDD.DLLは自作のDLLでしょうか?
>MFCを使ううえで必要なDLLではなくて。
BBB.DLL〜DDD.DLLは自作のDLLです。EEE.DLL〜GGG.DLLも自作のDLLです。
正確に言うと他人が作ったDLLです。
とりあえず、経緯がわかるようにリンクを張ったほうがいいです。
引用文だけ載せても意味不明だと思いますし。
はい。度々すいません。リンクです。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200612/06120049.txt
最小構成にしてみました。→は呼び出し関係です。
Win32 App → MFC通常DLL → MFC拡張DLL
(test.exe → testRegDll.dll → testExtDll.dll)
test.exeで、HMODULE hDll = LoadLibrary("testRegDll.dll")を実行すると、
デバックウィンドウに下記が表示されます。
AAA.DLL Initializing!
BBB.DLL Initializing!
CCC.DLL Initializing!
DDD.DLL Initializing!
・AAA.DLL〜DDD.DLLはMFC拡張DLLです。
・testRegDll.dllとtestExtDll.dllとAAA.DLL〜DDD.DLLは、全て同じ
ディレクトリにあります。
いったいどういう事でしょうか?
追記です。
・testRegDll.dllとtestExtDll.dllは、静的リンクを使っています。
・AAA.DLL〜DDD.DLLも静的リンクを使っています。
再追記です。
正常だと、HMODULE hDll = LoadLibrary("testRegDll.dll")を実行すると、
testExtDll.dll Initializing!
が表示されるのではないでしょうか?
どこからもつかっていないDLLはロードされていないんですよね?
たとえば
・AAAA.DLL は BBBB.DLL を必要としている
・BBBB.DLL は CCCC.DLL を必要としている
となっていれば、AAAA.DLLをLoadLibraryすればすべてロードされるのではないでしょうか。
で、その最小の実験コードでは
>AAA.DLLは
>使っていますが、BBB.DLL〜DDD.DLLは使っていません。AAA.DLLでも
>BBB.DLL〜DDD.DLLは使っていません。また、AAA.DLLでは、EEE.DLL,FFF.DLL
>とGGG.DLLを静的リンクしているのですが、これが、表示されていません。
という現象はおきているのでしょうか?
不可解なので、そのディレクトリからAAA.DLL〜DDD.DLLを削除しました。
この状態で、HMODULE hDll = LoadLibrary("testRegDll.dll")を実行すると、
「test.exe - コンポーネントが見つかりません
AAA.DLLが見つからなかったため、このアプリケーションを開始できません
でした。アプリケーションをインストールし直すとこの問題は解決される
場合があります。」が表示されます。全くもって不可解です。
Dependency Walker でtestRegDLL.dllを開いたときのDLLの一覧は下記の
とおりです。
GDI32.DLL
KERNEL32.DLL
MFC42D.DLL
MSVCRTD.DLL
NTDLL.DLL
TESTREGDLL.DLL
TESTEXTDLL.DLL
USER32.DLL
以上、よろしくお願いします。
>どこからもつかっていないDLLはロードされていないんですよね?
どこからも使っていないDLLがロードされています。
testRegDll.dllからは、testExtDll.dllのみを使っています。
testRegDll.dllからは、AAA.DLLを使っていません。
testExtDll.dllからも、AAA.DLLを使っていません。
Dependency Walker でtestExtDLL.dllを開いたときのDLLの一覧は下記の
とおりです。
GDI32.DLL
KERNEL32.DLL
MFC42D.DLL
MSVCRTD.DLL
NTDLL.DLL
TESTEXTDLL.DLL
USER32.DLL
以上、よろしくお願いします。
>testRegDll.dllからは、testExtDll.dllのみを使っています。
>testRegDll.dllからは、AAA.DLLを使っていません。
?
testRegDll.dll は testExtDll.dll を使っている。
では testExtDll.dll はほかに DLL を使っていないのか?
どうもすいません。私が大馬鹿者でした。
最小構成はうまくいきました。
古いDLLが、同じ名前で C:\WINDOWS\system32 に在り、こちらが先にロード
されていたので、こいつがAAA.DLL〜DDD.DLLを使っていました。
結局、古いDLLが、同じ名前で C:\WINDOWS\system32 に在り、こちらが先に
ロードされていたのが、Win32 App よりMFC通常DLL内の関数が呼び出せない
原因でした。古いDLLを削除すると、Access VBA からもMFC通常DLL内の関数が
呼び出せるようになりました。最小構成にもう一つMFC拡張DLLを使うように
追加(例えば、AAA.DLLを追加)しても、動くようになりました。
あと、問題は、MFC拡張DLLに対してCDynLinkLibrary()の位置を変更しなければ
ならない事です。あるMFC拡張DLLは、他のMFC拡張DLLから一つのクラスとして
扱っているので、CDynLinkLibrary()の位置を簡単に変えるわけにはいきま
せん。
一応、本来の質問は解決しましたのでクローズします。
Blueさんには、貴重な時間をさいていただき、大変お世話になりました。
どうもありがとう!
ははは! 解決のチェックを忘れていました。
>あと、問題は、MFC拡張DLLに対してCDynLinkLibrary()の位置を変更しなければ
>ならない事です。あるMFC拡張DLLは、他のMFC拡張DLLから一つのクラスとして
>扱っているので、CDynLinkLibrary()の位置を簡単に変えるわけにはいきま
せん。
MFCレギュラーDLLから呼んでいるMFC拡張DLLだけ、CDynLinkLibraryの処理を変えればいいと思います。
(MFC拡張DLLからMFC拡張DLLを呼ぶところは変更しなくいい)
例※)
MFCレギュラDLL MFC拡張DLL MFC拡張DLL
AAAA.DLL---> BBBB.DLL ----> CCCC.DLL
---> DDDD.DLL
---> EEEE.DLL ----> FFFF.DLL
ってなつくりなら、BBBB.DLL,DDDD.DLLおよびEEEE.DLLの変更でよいとおもう。
※掲示板上ではプロポーショナルフォントを扱っているため、
位置がずれまくると思うので見づらい場合、等幅フォントで見れるテキストエディタ
にコピペして確認してください。
ちなみに、DLLのロードの順番はおそらくLoadLibrary関数と同じで
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200609/06090062.txt
のBlue 2006/09/26(火) 17:49:40 に書いてある順番になります。
普通のアプリケーションであれば、1のロード元ディレクトリ
がexeのある場所にあるはずなので、たとえ古いDLLが2以降のディレクトリ
にあってもロードされないはずだと思います。
しかし、Access VBAなので、ロード元がMSACCESS.EXEになっちゃうのかな。
それと、2のカレントディレクトリもXXX.mdbだとどうもファイルがある場所ではないぽいです。
MsgBox CurDir
とデモして確認すると、私の環境(WinXPSP2/Office2003)ではマイドキュメントがカレントになっていました。
で、XXX.mdbのあるところにDLLをおいても何にも意味ないということになります。
一応 2 のカレントディレクトリを XXX.mdb のあるところにすることは可能です。
ChDrive CurrentProject.Path
ChDir CurrentProject.Path
とDLLの関数を呼ぶ前にカレントを移動すれば XXX.mdb にあるDLLがロードされるでしょう。
ただ、このカレントディレクトリってのはちょこちょこ変わる可能性があるので
気をつける必要があります。
>MFCレギュラDLL MFC拡張DLL MFC拡張DLL
> AAAA.DLL---> BBBB.DLL ----> CCCC.DLL
> ---> DDDD.DLL
> ---> EEEE.DLL ----> FFFF.DLL
>
>ってなつくりなら、BBBB.DLL,DDDD.DLLおよびEEEE.DLLの変更でよいとおう。
それがですね、こんな感じなんですよ。
MFC通常DLL MFC拡張DLL MFC拡張DLL MFC EXE
AAAA.DLL--->XXXX.DLL <---BBBB.DLL <---BBBB.exe
XXXX.DLL <---CCCC.DLL <---CCCC.exe
XXXX.DLLは、共通ライブラリとしての位置付けです。
BBBB.DLLとCCCC.DLLは、どちらかと言うとアプリとしての位置付けです。
XXXX.DLLは、BBBB.DLL等その他多く(数は約200?)のDLLから使っています。
AAAA.DLLが、今回、私が作っているDLLです。
XXXX.DLLには、例えばCXXXXという名前のクラスを定義して、この
クラスをBBBB.DLLから使います。
XXXX.DLLのDllMain()関数からnew CDynLinkLibrary()を削除すると、
CXXXXクラスの全てのメンバ関数とメンバ変数に対し、エクスポートを宣言
しないと、BBBB.DLLから使えないのでは?
では、AAAA.DLLをMFC拡張DLLとして、
それをラッピングするAAAAEx.DLL(MFC通常DLL)を用意してはどうでしょうか?
(AAAA.DLLは単なる橋渡しをするDLL)
DLLは1つ増えますが、既存の XXXX.DLL を変更しなくてよくなります。
こんな感じですか?
MFC通常DLL MFC拡張DLL MFC拡張DLL MFC拡張DLL MFC EXE
AAAARg.DLL--->AAAA.DLL--->XXXX.DLL <---BBBB.DLL <---BBBB.exe
XXXX.DLL <---CCCC.DLL <---CCCC.exe
AAAARg.DLLのInitInstance()関数で、AAAA.DLLのエクスポートした
拡張DLL初期化関数(CDynLinkLibraryが入っている関数)を呼ぶ?
>(AAAA.DLLは単なる橋渡しをするDLL)
AAAARg.DLLの事ですか?
> こんな感じですか?
そんな感じ。
>AAAARg.DLLの事ですか?
見方によって、どれが橋渡しになっているか微妙な気がしてきた。
VBとの橋渡しをするという見方ではAAAARg.DLLですね。
年末で時間も無いので、とりあえず橋渡しを作ってみます。
ツイート | ![]() |