22

私のプロジェクトは、メインの dll ライブラリにリンクする必要があるいくつかの静的ライブラリを介してビルドされ、結果として 1 つの dll が得られます。

属性を使用__declspec(dllexport)すると、スタティック ライブラリの指定された関数が dll に表示されなくなり、dll にリンクされていないライブラリがまったく表示されなくなります。

次に、エクスポートされた関数の適切な名前を取得するために各ライブラリを共有として構築し、それらに基づいて .def ファイルを作成しようとしました。.def ファイルを使用すると、結果が得られました。

  1. __declspec(dllexport)私の場合、平等に.def-file行動すべきですか?

  2. ソースから .def ファイルを生成することは可能ですか? 私は C++ コードを持っているので、API のマングリングとプレゼンス クラスのために自分で .def ファイルを書くことができません。一時的に生成された dll を使用した上記のアプローチは、本番環境では一貫性がありません。

アップデート

私のプロジェクトの構造について詳しく説明したいと思います。このソリューションは、いくつかのプロジェクト (モジュール) で構成されています。

+ 
|    
+-+ static_lib1                                          
|       +                                                
|       +--+ src                                         
|                                                        
+-+ static_lib2                                          
|       +                                                
|       +--+ src                                         
|                                                        
+-+ dynamic_lib (linked with static_lib1 and static_lib2)
        +                                                
        +--+ src

各サブプロジェクトは、他のサブプロジェクトに弱く依存しています。明確にするために、それらが接続されていないと仮定しましょう。各モジュールには独自のパブリック インターフェイスがあります。すべてのモジュールを単一の動的ライブラリとして保持したいので、アーティファクトは ですdynamic_lib.dllが、実際には静的ライブラリはリンクされていません。

4

2 に答える 2

20

静的ライブラリには、何も含めないで__declspecください__attribute((dll...))。それらは複数のオブジェクト ファイル (通常は*.objまたは*.o) であり、1 つの単一ファイルに構成されます。

そのようなライブラリを ( または のいずれかで) 使用するために必要なこと.exe.dll、適切なヘッダーを含めてそれらをリンクすることだけです。Visual Studio では非常に簡単です。

まず、1)静的ライブラリが配置されている場所と2)それらの正確な名前を知る必要があります。プロジェクトのプロパティに移動し、次にGeneral. Target name出力ファイルの名前を含み、配置されるOutput directoryフォルダーを示します.lib

注:このパスはプロジェクトごとに異なる場合があります。マルチプロジェクト ソリューションの場合、構成の問題を回避するために、これを常に共通のパスに設定します。

次に、このライブラリを使用するプロジェクトのプロパティに移動します (リンクします)。Linker->に移動しInput、次にあなたの名前を追加します.lib(Additional dependenciesエントリはセミコロンで区切られます):

リンカー入力

リンクしたいすべてのライブラリを追加する必要があります。また、これらのライブラリが配置されているフォルダをLinker-> General->に追加する必要がありAdditional library directoriesます。すべて.libの が同じ場所に配置されている場合は問題ありません。それ以外の場合は、それらを共有の場所にコピーするか、複数のエントリをAdditional library directoriesリストに追加します。

最後に、使用する関数とオブジェクトの宣言を含むヘッダーも含める必要があることを忘れないでください。基本的なことは知っていますが、言及する必要があります。


アップデート

外部プロジェクトで dll ライブラリを使用しようとすると、未解決の外部エラーが発生する

あなたの問題は、リンクとはまったく関係ありません。問題は、静的ライブラリをリンクすると正確に何をするのかを誤解していることです。

未解決として報告された関数は、あなたの では使用されていないと思いますDLLよね? しかし、あなたは彼らがその中にいることを期待していますよね?

外部コンテンツ (関数や変数など)をDLL参照すると、リンク時にすべての依存関係と共に解決されます。しかし、それだけです。静的ライブラリに という名前の関数があるprint_sample_string()が、それを使用しDLLいない場合、それは画像に添付されませんDLL。これについてよく考えてみてください。

さらに、dllexport明示的に編集されていない関数は表示されません。関数にはデフォルトで外部ストレージがあるため、基本的には privateDLLのコンテンツです。

したがって、質問に直接答えるには、 から関数/変数を使用する必要がある場合はstatic_lib1.lib、クライアント アプリケーションに添付してくださいdynamic_lib。他に方法はありません。(*)


(*)本当のことをいうと、あります。で中間関数を作成しDLL、それをエクスポートして、内部で目的の関数を呼び出すことができます。

のどこかdynamic_lib:

DLL_EXP_IMP long CallFunctionFromA_Lib()
{
     return some_function(); //this function is from static_lib1.lib
}

のどこか.exe:

long result = CallFunctionFromA_Lib(); //internally this will call function from static_lib1.lib

A.libしかし、単純にリンクして直接使用するのではなく、なぜこれを行いたいのか想像できません。

于 2015-07-16T06:34:43.473 に答える
4

ここでは、Raymond Chan がこの動作について説明しています。最善の解決策は、def ファイルを使用することです。静的ライブラリに対して自動的に生成する方法については、この議論は良い出発点のようです。

于 2015-07-16T13:58:06.883 に答える