Win32 の環境で、EXEファイルをDLLとして使用可能か?
ということが知りたくて書かせていただきました。
現在、VC++v6 下、MFCを使ってフリーソフトを作っておりますが、
この EXEファイルの中にある関数を exportして、別アプリ
からさもDLLとして見えるようにしたいのです。
で、以下の実験をしてみました。
VC++で3つのプロジェクトを作りまして、
上記「アプリ」に相当するテストプログラム(Exedll)
上記「別アプリ」に相当するテストプログラム(main)
正真正銘のDLLとして作ったテストプログラム(Dlldll)
です。
main から Exedllの中の関数と、Dlldllの中の関数を
コールして違いを比べてみたのですが、
特にmainから見て違いは感じられませんでした。
Exedllでもちゃんと動くようです。
# LoadLibrary して GetProcAddress してと言う一連の
# 処理が滞りなくおこなえる。
ひとまずは、Exedllでexportする関数は、2つ変数を
とって、その和をリタン値として返すと言う単純な
ものです。
MFCの関数(AfxMessageBox)を呼んだらそこで落ちてしまいました。
# どうしてかの 考察は後述
本番でも、メモリ上の情報を処理してメモリ上に
展開しこれをメインに返すという基本的な機能を export
しようと思っています。
# つまり、ウインドウを開いたり等は行わない。
ですから状況としては、「EXEをDLLとして使用可能」と
思えるのですが、MSDNを見渡しても、「して良い」とも
「してはいけない」と言う記述を発見できませんでした。
もちろん、ただ、私の探しかたが足らなかっただけ、
なのかも知れませんので、ご指摘ください。
MSDNで、DLLについての記述を見て行くと、
DLLの場合もEXEファイルと同じくローディング後に、
EntryPointに処理が移り、これが、DllMainとして、
見える事は分かりました。
そこで、
Exedll の WinMainCRTStartup と
Dlldll の _DllMainCRTStartup の両方にブレークポイント
を置いて待ち構えていたのですが、
当然、_DllMainCRTStartup では、止まるのですが、
WinMainCRTStartup では止まりませんでした。
# 当然 theApp のコンストラクタにも処理が移らない
従って、MFCや、Cのライブラリに必要な値の初期化等が
行われることなく、exportした関数がコールされているよう
に見受けられます。
このため、MFCの関数をコールすると落ちてしまったので
しょう。逆に、本来のEXEとしての動作も行われなかった
のだと思われます。
_DllMainCRTStartup は、カーネルからコールされるのでは
なくて、NTDLL というところからコールされているように
見受けられます。(ブレークポイントで止めて、CallStack
で見ると)このNTDLLと言うものは何でしょうか?
多分、このNTDLLと言うのが EXEをLoadLibraryしたときに
「これはDLLでないからEntryPointを呼ぶのは止めた」と
判断しているようみうけられるわけですが、
この理解で正しいのでしょうか?
昔は、DLLと言う拡張子はなくて、EXEを使っていたよう
ですし、(間違っているかも?)
EXEをDLLとして使えるのでしょうか?
# Testは WindowsNT上で行いました。
exeとしても使えるし、dllとしても使えるということになると
startupルーチンが違う点が問題になりますね。
一版にexeではTerminateProcessみたいな関数を最後に呼びますが
dllは呼ばないという違いもあります。
それと、もう一つあるのは、PEフォーマットの中にはdllフラグ
というのがあって、dllのときに意味をもっています。
この値が悪さするのではないかという気もします。
Hideo Shimizu <hi...@isl.rdc.toshiba.co.jp> wrote in message news:3A3DDFBF...@isl.rdc.toshiba.co.jp...
PE Formatについて MSDNを漁ってみました。
確かに、IMAGE_FILE_HEADERの中に IMAGE_FILE_DLL というのがあって
これでDLLを表現できるようです。
QuickViewで表示されるのは、これらの情報である事がわかりまして、
「なるほど」というところです。
貴重な情報をありがとうございました。
NTDLLについて、調べておりましたが、
NTDLL.DLLというDLLが存在することが分かりまして、
これは憶測ですが、多分、DLLをコールする時には常にこの
NTDLL.DLLのお世話になっているようです。
名前からしてNTのみのDLLかしらと思い、
Windows98と Windows95 で調べてみたら、両方共にちゃんと
存在していました。
これが関係しているのでしょうか?
NTのNTDLL.DLLの中には、 LdrLoadDLL というシンボルが
Exportされていました。(MSDNには記述なし?)
DLLの中にLdrLoadDLLがあるのは何とも変な感じがするのですが、
何かご存知のかた教えてください。