MFC拡張DLLのリソースID

[戻る]
いしだ 2007/10/13(土) 20:56:03
VS2005でMFC拡張DLLを複数作成し、
それらを参照し合うアプリケーションを作成しています。
各拡張DLLは、内部で文字列やダイアログなどのリソースを持っています。

昔VC6で同じように拡張DLLを作成していた頃は、
リソースIDが他の拡張DLLやアプリケーションと重なってはいけない
という制限があったと記憶しているのですが、
VS2005でもこのような制限はあるのでしょうか?
それとも、自由にリソースIDを決めてしまってもよくなったのでしょうか?

MSDNやネットでもいろいろ探してみたのですが、探しかたが悪いのか、
VC6時代のMFCを対象に書かれたと思われるものが多く、
いまいち確信が持てずに困っています。
どなたかご存じないでしょうか。
よろしくお願いいたします。

wclrp ( 'o') 2007/10/16(火) 00:00:28
>リソースIDが他の拡張DLLやアプリケーションと重なってはいけない

読みたいリソースをもつDLLのモジュールハンドルを指定すれば
同じIDでもちゃんとそのDLLの方から読んでくれるよ。

たぶん
それって
指定しない使い方をする場合の
注意事項だったんじゃないの。

あるいはDLLからEXEのコールバックを呼び出してEXEがリソース読むとか
ややこしいつくりの場合は
ハンドルの指定をもどしていないから・・・
という場合のことを考えたんじゃないの。

maru 2007/10/16(火) 11:17:17
> いしだ 2007/10/13(土) 20:56:03
> 昔VC6で同じように拡張DLLを作成していた頃は、
> リソースIDが他の拡張DLLやアプリケーションと重なってはいけない
> という制限があったと記憶しているのですが、
拡張DLLって普通のDLLと違うんですか?
こんな話はVC6以前からも記憶にありません。
この情報のソースは何でしょうか?

実際に、多国語対応アプリケーションではリソースを言語毎にDLLに入れて、
言語ID毎にDLLを切り替えることで対応している物が多々あります。この場
合、ソースコード側は言語に依存しないようにするため、同じリソースIDを
使用します。

maru 2007/10/16(火) 11:35:31
失礼しました。
> maru 2007/10/16(火) 11:17:17
> 拡張DLLって普通のDLLと違うんですか?
おっと、MSDNライブラリに「拡張 DLL」っていうキーワードがあった。

MSDNより引用
「リソースのエクスポートには、リソース リストを使います。各アプリケーションには、
CDynLinkLibrary オブジェクトの単方向リストが含まれています。リソースをロードする標準
的な MFC インプリメンテーションでは、リソースを検索するとき、まず現在のリソース モジ
ュール (AfxGetResourceHandle) を探します。ここで見つからないときは、
CDynLinkLibrary オブジェクトのリストを順に探して必要なリストをロードします。」

「リソースを標準的な MFC インプリメンテーションでは」リソースを検索するときに
アプリケーション->拡張DLLの順に検索するので、重複してはいけない。
(重複した場合、後のリソース無視されることになる)。

だから
> たぶん
> それって
モジュールハンドルを
> 指定しない使い方をする場合の
> 注意事項だったんじゃないの。
ということみたいですね。

Kerry 2007/10/16(火) 12:02:43
> VS2005でもこのような制限はあるのでしょうか?

変わっていません。
しかし、それは制限というより、EXEやDLL間で「リソースをシームレスに共有できる」
という拡張DLLの利点でもあると思います。

正確には、IDが重なってはいけない、というより、同じIDを持つリソースは、リソース
チェインの中で先に見つかったものがロードされる、という仕様です。
これを利用して、DLL側で定義されているリソースをEXE側でオーバーライドする、とい
ったことが可能になります。

いしだ 2007/10/16(火) 13:21:06
みなさんありがとうございます。
VS2005でも拡張DLLのリソースIDは
プロジェクトをまたいで管理しないといけないのですか。

> これを利用して、DLL側で定義されているリソースをEXE側でオーバーライドする、
> といったことが可能になります。

たしかにこのようなメリットもあるかと思うのですが、
たとえば独自のクラスを拡張DLLとして複数作成しておき、
それを他のプロジェクトチームのアプリケーションで何個か選んで使う場合、
内部で使うダイアログなどのリソースIDは、
この拡張DLLを使うアプリケーション内のリソースIDとも
被ってはいけないということになりますし、
使われる拡張DLL間でも被らないようしなければいけないのですよね。

やはり他のプロジェクトチームなどに提供する場合は、拡張DLLごとに
「内部で○〜○のリソースIDを使っているので、この範囲は使わないこと」
みたいな制限をする必要が出てくるのでしょうか?

Kerry 2007/10/16(火) 13:42:44
> やはり他のプロジェクトチームなどに提供する場合は、拡張DLLごとに
> 「内部で○〜○のリソースIDを使っているので、この範囲は使わないこと」
> みたいな制限をする必要が出てくるのでしょうか?

そのとおりです。
MFC自身も、0x7000〜0x7FFFまでがMFC内部用に予約されており、アプリケーションがこ
の範囲を使用することはできませんし、それと同じような運用が必要になります。

いしだ 2007/10/16(火) 14:11:16
[[解決]]
> MFC自身も、0x7000〜0x7FFFまでがMFC内部用に予約されており、
> アプリケーションがこの範囲を使用することはできませんし、
> それと同じような運用が必要になります。

なるほどやはりそうなのですか。

別のプロジェクトで作った拡張DLLがたまたま同じリソースIDを使っていたら、
基本的には他のプロジェクトではそのまま流用はできないということですか。
下手に拡張DLLを分散させると、リソースIDの管理がやっかいですね。
ビルド自体は通ってしまいますから、エラーに気づきにくいですし。

ありがとうございます。

古いスレッドには追加発言できません。