2009-03-01 8 views
20

Visual StudioにlibファイルのすべてのシンボルをatmとしてDLLにリンクする方法はありますか?これは、プログラムによって必要とされる "未使用"実行時のdll。libファイル内のすべてのシンボルをリンクするVisual Studioを強制する

私は/ OPT:NOREFと/ OPT:NOICFを使ってみましたが、うまくいきません。彼らは彼らにコントローラと自己を登録グローバルクラスであり、彼らは、DLLにリンクされていないので、私はそれらを必要と

理由があります。

+0

コンパイルとリンクに使用している完全なコマンドラインをリストできますか? –

答えて

19

Visual Studioで、よりエレガントな方法があるかどうかはわからないが、我々はそれを使用するクロスプラットフォームソリューションをリンクするproblamaticオブジェクトファイルを強制的に二つのマクロを持っています。

一つが除外されている機能のソースファイル内に配置され、他のは、リンカが呼び出されます知っている関数に配置されます。

類似のもの;

#define FORCE_LINK_THIS(x) int force_link_##x = 0; 

#define FORCE_LINK_THAT(x) { extern int force_link_##x; force_link_##x = 1; } 

これはまったくエレガントではありませんが、プラットフォーム間で機能する優れたソリューションは見つかりませんでした。

+0

非常にかわいい。なぜ '__declspec(dllexport)'は十分ではないのですか? –

+1

'__declspec(dllexport)'と '__declspec(dllimport)'は、コードがDLLにあることを(コンパイラに対して)宣言しているため、十分ではありません。これにより、サンク機能と.DEFファイルが不要になります。 ちょっとマイナーな最適化: '#define FORCE_LINK_THAT(x) void force_link_function _ ## x(void){extern int force_link _ ## x; force_link _ ## x = 1; } ' はリンクされることがわかっているファイルの先頭にマクロを配置することができます。それは、ダミー関数が決して呼び出されないという違いをBTWはしません。 –

+1

また、空の本体を持つ関数で動作するようです。 libをリンクしている実行可能ファイルまたはdllのどこかに呼び出してください。 – BigSandwich

0

DLLは実行時にlibから関数をどのように呼び出すのですか?それは信じがたいです。

DLLのユーザーがのユーザーがあなたのライブラリ関数を呼び出そうとしている場合、あなたの質問は意味があります。 Windowsコンパイラ(Unixコンパイラとは異なり)は、明示的に要求された場合にのみDLLから関数をエクスポートします。これを行う最も一般的な方法は、関数 "dllexport"を宣言することですが、.DEFファイル内の関数の名前をリンカーに渡すこともできます。 .DEFファイルにC++の変更された名前をリストする必要があることに注意してください。

+0

彼らはコントローラで自分自身をregするグローバルクラスであり、dllでリンクされていないためです。 – Lodle

+0

それを質問に入れておくと便利でしょう。それは良い質問ですが、その追加が、あなたが今質問したものとは異なります。 – MSalters

1

私は様々なのDLLの工場が共通の主力工場、ライブラリをロードするときにハードに使用するプラグインのリストをコンパイルすることなく、起動時に登録するすべてのものを使用していたプラグインシステムと同じ問題を抱えていました。これはLinux上ではうまくいっていましたが、Windowsでは2つの問題がありました。

  1. 工場はDLL間で共通ではありませんでした。これはあなたの問題ではありませんが、それは関連しています。私はここに解決策を得た:Ensuring to use common fatories。ジェームズの答えをset_the_global関数で見てください。
  2. メインでDLLのシンボルが使用されていない場合は、起動時にセットアップされませんでした。私はそれがあなたの問題だと思う。私が見つけた唯一の解決策は、使用可能なプラグイン(DLL)の名前をリストした構成ファイル(サブプロジェクトごとに1つ)を使用し、私の場合はQLibraryを使用してリンクを強制することでした。 cmakeのを使用して、各サブプロジェクトの設定ファイルのデフォルトのバージョンは、各プラグインのディレクトリに代わりadd_libraryのと呼ばれる、次のマクロを使用してビルド時に生成されます。

    file(WRITE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-plugins "") 
    macro (DECLARE_AMOSE_PLUGIN _plugin) 
        file (APPEND ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-plugins "${_plugin}\n") 
        add_library(${_plugin} SHARED ${${_plugin}_LIB_SRCS}) 
    endmacro (DECLARE_AMOSE_PLUGIN) 
    
0

私はプラグマを使用し、それがいるようです作業はしていますが、行を含めなければチョークしません。

#include "library1.h" 
#include <QApplication> 
#pragma comment(lib, "C:\\Qt\\5.5\\msvc2013_64\\lib\\Qt5Guid.lib") 
PHI_STATUS PHI_EXP_CONV PHI_ShowGUI(size_t reserved) 
{ 
    QApplication app(none, nullptr); 
    ... 
} 

またLibrarianタブでAdditional Dependenciesフィールドを経由して、それらをリンクすることができます。

3

実際には半公式の解決策があり、here it isです。

TL; DR:

'を使用するライブラリの依存入力'

「ライブラリ依存関係入力」は、ライブラリを構成するobjファイルの名前です。あなたは実際に2つのスコープでこの動作を制御することができますrefernceパー

  1. :参照プロパティで コンボ「ライブラリの依存入力を使用」で。これは私が を個人的に使った解決策と、in the postと書いたものです。実行可能ファイル全体毎Use Library Dependency Inputs

  2. :EXEプロジェクトで プロパティ/ C++ /リンカ/一般/使用ライブラリの依存入力 - >はい

これらの難解な設定のための歴史的な動機はenabling incremental linking in places it wasn't available beforeですが、それlibにパッケージ化されているobjファイルと直接リンクすることで、参照されていないグローバルオブジェクトも構築するという便利な副作用があります。 MSVC2k17でテスト

0

...

__pragma(comment(linker,"/export:REGISTERfunc")); 
void REGISTERfunc() { printf("I'm linked!\n"); } 

は完全に動作します。これは、静的にリンクされた.lib内にあっても、実行可能ファイルと実行可能ファイルに至るまですべてを経由します。

EDIT:あなたは素晴らしいポイントのためにマクロに入れることもできます!

EDIT:別の注意:リンクタイムコード生成を有効にする必要があります。/LTCG ... something

関連する問題