エントリがDLLファイル内に見つかりません。(続)

解決


ちょろねずみ  2006-12-27 18:55:34  No: 64083

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です。


Blue  2006-12-27 19:08:48  No: 64084

とりあえず、経緯がわかるようにリンクを張ったほうがいいです。
引用文だけ載せても意味不明だと思いますし。


ちょろねずみ  2006-12-27 22:07:00  No: 64085

はい。度々すいません。リンクです。
http://madia.world.coocan.jp/cgi-bin/VBBBS/wwwlng.cgi?print+200612/06120049.txt


ちょろねずみ  2006-12-27 23:23:54  No: 64086

最小構成にしてみました。→は呼び出し関係です。

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は、全て同じ
  ディレクトリにあります。

いったいどういう事でしょうか?


ちょろねずみ  2006-12-27 23:28:19  No: 64087

追記です。
・testRegDll.dllとtestExtDll.dllは、静的リンクを使っています。
・AAA.DLL〜DDD.DLLも静的リンクを使っています。


ちょろねずみ  2006-12-27 23:33:35  No: 64088

再追記です。
正常だと、HMODULE hDll = LoadLibrary("testRegDll.dll")を実行すると、

testExtDll.dll Initializing!  

が表示されるのではないでしょうか?


Blue  2006-12-27 23:36:52  No: 64089

どこからもつかっていない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を静的リンクしているのですが、これが、表示されていません。
という現象はおきているのでしょうか?


ちょろねずみ  2006-12-28 00:03:03  No: 64090

不可解なので、そのディレクトリから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

以上、よろしくお願いします。


ちょろねずみ  2006-12-28 00:07:26  No: 64091

>どこからもつかっていないDLLはロードされていないんですよね?
どこからも使っていないDLLがロードされています。
testRegDll.dllからは、testExtDll.dllのみを使っています。
testRegDll.dllからは、AAA.DLLを使っていません。


ちょろねずみ  2006-12-28 00:15:34  No: 64092

testExtDll.dllからも、AAA.DLLを使っていません。

Dependency Walker でtestExtDLL.dllを開いたときのDLLの一覧は下記の
とおりです。

GDI32.DLL
KERNEL32.DLL
MFC42D.DLL
MSVCRTD.DLL
NTDLL.DLL
TESTEXTDLL.DLL
USER32.DLL

以上、よろしくお願いします。


Blue  2006-12-28 00:17:04  No: 64093

>testRegDll.dllからは、testExtDll.dllのみを使っています。
>testRegDll.dllからは、AAA.DLLを使っていません。

testRegDll.dll は testExtDll.dll を使っている。
では testExtDll.dll はほかに DLL を使っていないのか?


ちょろねずみ  2006-12-28 01:09:26  No: 64094

どうもすいません。私が大馬鹿者でした。
最小構成はうまくいきました。
古いDLLが、同じ名前で C:\WINDOWS\system32  に在り、こちらが先にロード
されていたので、こいつがAAA.DLL〜DDD.DLLを使っていました。


ちょろねずみ  2006-12-28 02:09:31  No: 64095

結局、古い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さんには、貴重な時間をさいていただき、大変お世話になりました。
どうもありがとう!


ちょろねずみ  2006-12-28 02:10:27  No: 64096

ははは!  解決のチェックを忘れていました。


Blue  2006-12-28 02:19:01  No: 64097

>あと、問題は、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の変更でよいとおもう。

※掲示板上ではプロポーショナルフォントを扱っているため、
  位置がずれまくると思うので見づらい場合、等幅フォントで見れるテキストエディタ
  にコピペして確認してください。


Blue  2006-12-28 02:37:05  No: 64098

ちなみに、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がロードされるでしょう。
ただ、このカレントディレクトリってのはちょこちょこ変わる可能性があるので
気をつける必要があります。


ちょろねずみ  2006-12-28 03:33:40  No: 64099

>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から使えないのでは?


Blue  2006-12-28 05:48:41  No: 64100

では、AAAA.DLLをMFC拡張DLLとして、
それをラッピングするAAAAEx.DLL(MFC通常DLL)を用意してはどうでしょうか?
(AAAA.DLLは単なる橋渡しをするDLL)
DLLは1つ増えますが、既存の XXXX.DLL を変更しなくてよくなります。


ちょろねずみ  2006-12-28 06:26:50  No: 64101

こんな感じですか?

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の事ですか?


Blue  2006-12-28 18:44:31  No: 64102

> こんな感じですか?
そんな感じ。

>AAAARg.DLLの事ですか?
見方によって、どれが橋渡しになっているか微妙な気がしてきた。
VBとの橋渡しをするという見方ではAAAARg.DLLですね。


ちょろねずみ  2006-12-28 18:53:44  No: 64103

年末で時間も無いので、とりあえず橋渡しを作ってみます。


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

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






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