DLLのロードについて


まもる  2010-08-24 22:52:38  No: 71893  IP: 192.*.*.*

お世話になります。

環境は WinXP Pro  VS2005 C++ SDKスタイル です

DLLを作って利用するソフトを作ろうとしています。
基本的には以下のような感じかと思うのですが

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
           )
{
    // 初期化   

    return TRUE;
}



extern "C" __declspec(dllexport)
int __stdcall func_A(int i, int j)
{
    // 処理

   return 0;
}

この DLLを利用するアプリが起動する時に DLLも同時にロードして
DllMain()の中の初期化を一度だけしか行わないようにし、アプリが
終了する時は DLLも終わらせたいのですがどうすればよいのでしょうか?

いろんなキーワードで検索したもののそれらしき情報を得ることが
できませんでした。

キーワードや参考になるサイトをご存知でしたらよろしくお願いします。

編集 削除
瀬戸っぷ  2010-08-25 00:56:11  No: 71894  IP: 192.*.*.*

>この DLLを利用するアプリが起動する時に DLLも同時にロードして

DLLをビルドしたときに.libファイルが作成されているかと。
その.libをアプリ側でリンクすればよい…んじゃないですかね?
# やったことないんですが…

編集 削除
まもる  2010-08-25 06:15:35  No: 71895  IP: 192.*.*.*

瀬戸っぷさん コメントありがとうございます。

すみません説明不足で申しわけないです。
DLLを作るのは VC++ なのですが、それを利用するのは C# VS2005 で 
.NET 2.0 の環境なんです。

そのうえで、C#で作製したアプリの起動と当時に DLLも静的に
ロードできないかと思いまして

編集 削除
仲澤@失業者  2010-08-25 10:29:36  No: 71896  IP: 192.*.*.*

>DllMain()の中の初期化を一度だけしか行わないようにし、アプリが

これはDLL側の実装で、DllMain()の第2引数fdwReasonが
DLL_PROCESS_ATTACHの時にやればよいだけで、特に頭を
使う必要はありませんよねぇ。詳しくはマニュアルを
見てください。

>この DLLを利用するアプリが起動する時に DLLも同時にロードして

C#はあんまり詳しくないのですが、Load on Call動作なんでしょうか
だとしても、開始関数Start()かなんかをDLLに用意して、コールすれば
Start()の実行は、
  => DLL のLoadLibrary => DllMain( h,DLL_PROCESS_ATTACH)を実行
  => Start()関数の実行
の順で実行されるので問題なしですね。

>終了する時は DLLも終わらせたいのですがどうすればよいのでしょうか?

これは、OSの仕組み上「できない」が正解です。別のプロセスが
このDLLを使っていれば解放することはできません。これは、
ネイティブコードでも事情は同じなのであきらめましょう。

編集 削除
ryo  2010-08-25 12:44:14  No: 71897  IP: 192.*.*.*

追い出すような物言いになってしまうのですが・・・

これは、呼び出す側の、つまりC#での手法の話になるので
C#をメインとした掲示板などで質問されたほうがいいのではないでしょうか?

編集 削除
まもる  2010-08-25 16:11:56  No: 71898  IP: 192.*.*.*

仲澤@失業者さん
 コメントありがとうございます。
 DllMain が呼ばれるたびにファイルに文字を追記するコードを書いて実験したところ
 その DLL内の関数を呼ぶたびに DllMainが呼ばれることがわかったので何とか
 せねばと思った次第です。

ryoさん どうもです。
 DLLを作る VC++側で何とかできるものかと思ったのですが
 結果的にカテ違いの質問だったようです。


みなさんからアドバイスいただいているうちに適切な言葉が見えてきまして再調査すると

[DllImport("kernel32")]
private extern static int LoadLibrary(string lpLibFileName);

みたいに LoadLibrary まで C#側から使えるようにしないとダメなようです。
ここまでわかっただけでも前進でした。
ありがとうございます。

編集 削除
仲澤@失業者  2010-08-25 18:59:49  No: 71899  IP: 192.*.*.*

>その DLL内の関数を呼ぶたびに DllMainが呼ばれることがわかったので
>何とか せねばと思った次第です。

そうなります。ですが、fdwReasonがDLL_PROCESS_ATTACHのケースは
1回だけのはずです。その他は全てDLL_THREAD_ATTACHかDLL_THREAD_DETACH
で来るはずです。
DLL_PROCESS_DETACHも最後に一回だけが来るはずです。

編集 削除
まもる  2010-08-26 06:54:35  No: 71900  IP: 192.*.*.*

仲澤@失業者さん
重ね重ねありがとうございます。

と言うことは LoadLibraryが使えなくても C#からアンマネージドDLLを
呼び出すときに fdwReason に DLL_PROCESS_ATTACH をセットできれば
良いわけですね、やり方があればこちらの方が手軽そうですね

#プライオリティの高い作業が割り込んできたためちょっと実験は保留です><

編集 削除
仲澤@失業者  2010-08-26 09:30:42  No: 71901  IP: 192.*.*.*

>呼び出すときに fdwReason に DLL_PROCESS_ATTACH をセットできれば
>良いわけですね、やり方があればこちらの方が手軽そうですね

それはできません。その設定はOSがやります。
だから安全で確実に判定できるわけです。

編集 削除