40

静的ライブラリにリソースを構築し、ライブラリとリンクするだけでそれらを再利用することは可能ですか?

私は主に、ライブラリ内の関数を呼び出して、リソースにアクセスする場合について考えています。

4

7 に答える 7

63

Visual C++ (2008) のスタティック ライブラリでリソース (画像、ダイアログなど) を使用するために必要な唯一のことは、プロジェクトにスタティック ライブラリの関連する .res ファイルを含めることです。これは、「プロジェクト設定/リンカー/入力/追加の依存関係」で行うことができます。

このソリューションでは、スタティック ライブラリのリソースが .exe にパックされるため、追加の DLL は必要ありません。残念ながら、Visual Studio は .lib ファイルの場合のように .res ファイルを自動的にインクルードしませんが (「プロジェクトの依存関係」機能を使用する場合)、この小さな追加ステップは許容できると思います。

私はこのソリューションを非常に長い間探してきましたが、今では驚くほど簡単です。唯一の問題は、それが完全に文書化されていないことです。

于 2009-10-27T14:10:33.893 に答える
26

それはできますが、かなり面倒です。単に静的ライブラリとリンクするだけではできません。

これを考慮してください。リソースは EXE または DLL に埋め込まれています。スタティック ライブラリの一部のコードが (例: LoadIcon) を呼び出すと、リンクされている EXE または DLL からリソースを取得します。

そのため、静的ライブラリでリソースを利用できるようにする必要がある場合は、いくつかのオプションがあります。

  1. ライブラリにそれらをその場で構築させてから、 (eg) を使用できますCreateDialogIndirect。Raymond Chen の「実行時にダイアログ テンプレートを構築する」を参照してください。
  2. それらを単純な配列 (ie) としてライブラリに埋め込んでから、char my_dialog_resource[] = { .... };(eg) を使用できますCreateDialogIndirect.RESおそらく、ファイルからファイルに変換するユーティリティを見つける (または作成する) 必要があり.CPPます。
  3. リソース スクリプト (.RCファイル) と対応するヘッダー ファイルを含む LIB ファイルを出荷できます。次に#include、関連するものとしてそれらを選択します。LIB が使用するリソース ID の範囲を予約して、メインの EXE または DLL のリソース ID と競合しないようにする必要があります。これは、MFC がスタティック ライブラリとして使用される場合の動作です。または、文字列のリソース ID を使用できます (これはリソースには機能しませんSTRINGTABLE)。
  4. 静的ライブラリは、別のリソース DLL と共に出荷できます。
于 2009-02-10T10:20:37.017 に答える
11

私はMSVisualStudioコンパイラでこれを実行しました。いくつかのレガシープロジェクトをDLLから静的ライブラリに変換していました。これらのDLLのいくつかには、ダイアログまたは文字列リソースが埋め込まれていました。これらのDLLの.RCスクリプトを、「TEXTINCLUDE」メカニズムを介してメインアプリケーションのRCスクリプトファイルに含めることにより、メインアプリケーションにコンパイルすることができました。RCファイルを直接編集するのが最も簡単だと思いましたが、VisualStudioにはもう少し「奇妙な」メカニズムも用意されています。他のコンパイラでは、実装が異なる可能性があります。


メインRCスクリプトを直接操作するには:

.1。「2TEXTINCLUDE」セクションに、ライブラリのリソースIDを定義するヘッダーファイルをインクルードします。構文は

2 TEXTINCLUDE 
BEGIN
    "#include ""my_first_lib_header.h""\r\n"
    "#include ""my_second_lib_header.h""\0" 
END

.2。「3TEXTINCLUDE」セクションに、ライブラリのRCスクリプトを含めます。

3 TEXTINCLUDE
BEGIN
    "#include ""my_first_library.rc""\r\n"
    "#include ""my_second_library.rc""\0"
END

手順3と4は自動的に実行されるはずですが、Microsoftのリソーススクリプトコンパイラに依存して処理するよりも、自分で入力する方が信頼性が高いことがわかりました。

.3。ライブラリリソース定義を含むヘッダーファイルを読み取り専用シンボルリストに追加します。このリストは通常​​、ファイルの先頭近くにあります。

#define APSTUDIO_READONLY_SYMBOLS
#include "my_first_lib_header.h"
#include "my_second_lib_header.h"
#undef APSTUDIO_READONLY_SYMBOLS

.4。ライブラリのRCスクリプトをAPSTUDIO_INVOKEDセクションに含めます。これは通常、ファイルの下部にあります。

#ifndef APSTUDIO_INVOKED
#include "my_first_library.rc"
#include "my_second_library.rc"
#endif 

Visual Studio IDEを使用してこれらすべてを自動的に実行することもできますが、期待したときに常に適用されるとは限りませんでした。

  1. VisualStudioで[リソースビュー]ウィンドウを開きます。
  2. メインアプリケーションのリソースファイルを右クリックし、コンテキストメニューから[リソースに含める...]を選択します。
  3. [読み取り専用シンボルディレクティブ]というラベルの付いたボックスに、ライブラリのリソースIDを定義する.hファイルのincludeステートメントを追加します。
  4. [コンパイル時ディレクティブ]というラベルの付いたボックスに、ライブラリの.rcスクリプトのincludeステートメントを追加します。
  5. [OK]をクリックします。また、RCスクリプトのコンパイルを手動でトリガーして、確実に実行することもできます。

ライブラリのリソーススクリプトがディスク上のファイル(テキストファイル、アイコンファイルなど)を参照している場合は、メインアプリケーションプロジェクトがそれらのファイルの場所を認識していることを確認する必要があります。これらのファイルをアプリケーションが見つけられる場所にコピーするか、コンパイラ設定に追加のインクルードパスを追加することができます。

インクルードパスを追加するには:

  1. メインアプリケーションのプロパティダイアログを開きます。
  2. 左側のナビゲーションペインから[構成のプロパティ/リソース/一般]を選択します。
  3. プロパティリストで、[追加のインクルードディレクトリ]の横に関連するパスを入力します。
于 2009-06-24T18:27:02.507 に答える
2

Visual Studio 2010 によると、Microsoft の開発ツールは、静的ライブラリ内のコンパイル済みリソース データを適切に処理できないようです。

コンパイル済みのリソース ファイル (.resファイル) を配布するには、次の 2 つの選択肢があります。

  1. ファイルを個別に配布し、.resそれらに対してリンクするようにクライアント コードに指示します。
  2. 複数のファイルを 1 つのオブジェクト ( ) ファイルcvtresにマージし、個別に提供するために使用します。.res.obj

で作成されたオブジェクト ファイルでは lib できないことに注意してくださいcvtres。複数のオブジェクト ファイルが指定されている場合、複数のファイルが指定さlibれているかのように文句を言います。.res単一のオブジェクト ファイルが提供されている場合、エラーはlib発生しませんが、リンカは単に lib ファイルに埋め込まれたリソース データを無視します。

リソースデータは実際にライブラリで利用可能であるため(コマンドラインオプション、セクション操作などを使用して)、リンカにリソースデータのlibbedを読み取らせてリンクさせる方法がある場合があります(dumpbin明らかにする)。これまでのところ、私は解決策を見つけていません。また、開発ツールをハッキングする意思がない限り、この単純な解決策よりも優れたものは、おそらく努力する価値はありません。

静的ライブラリ (この場合は静的ライブラリ) でリソース データを出荷する唯一の方法、リソースを個別に配布し、クライアント コードで明示的にリンクすることです。を使用cvtresすると、分散リソース ファイルが多数ある場合に、その数を 1 つに減らすことができます。

于 2013-02-23T22:41:21.810 に答える
1

私はそうは思わない。静的ライブラリには、独自のHINSTANCEがありません。そのコードは、それをリンクするDLLまたはEXEのコンテキストで実行されます。そのため、静的ライブラリのコードからロードしようとするすべてのリソースは、DLL/EXEを囲むリソースになります。

ただし、DLLが独自のアドレス空間を持っている限り、そのようなリソースをDLLで再利用しました。また、DLLのHINSTANCEを使用してLoadResourceを呼び出すことができます。

于 2009-02-10T08:55:43.383 に答える
0

推奨される方法は、ライブラリと一緒にリソースを含む dll を提供することです。

于 2009-02-11T10:17:29.567 に答える