7

静的ライブラリの一部として、非常に基本的な「プラグインシステム」を実装しました。各「プラグイン」は、GIF、JPEGなどの特定の画像形式のサポートを実装します。さらに、PluginManager使用可能なすべてのプラグインのリストを保持するシングルトン(と呼ばれるクラス)があります。

トリッキーな部分は、プロジェクトファイルからソースファイルを追加または削除して、プラグインを無効/有効にしたいということです。これを実現するために、各プラグインは(異なる名前の)グローバル変数を作成し、そのクラスのコンストラクターにプラグインを登録しPluginManagerます。

JPEG形式の場合はこのようなものです...

struct JPEGPlugin
{
  // constructor will register plugin
  JPEGPlugin()
  {
    PluginManager::Singleton().RegisterPlugin(this);
  }

  // plenty of other code
  ...
};

JPEGPlugin jpeg_instance;  // instantiate in global scope

ただし、これは理論的には完全に機能しますが、この静的ライブラリを他のコードにリンクして実行可能ファイルをビルドする場合は失敗します。この実行可能ファイルがプラグイングローバル(のようにjpeg_instance)にアクセスしない限り、リンカーは接続を認識せず(コンストラクターの副作用を完全に無視します)、最終的な実行可能ファイルにコードを含めません。つまり、JPEGプラグインは最終的なアプリでは使用できません。

私は何年にもわたって何度か問題に遭遇し、常にネットで解決策を探しました。毎回、それは既知の問題であり、私はそれと一緒に暮らさなければならないと基本的に言っているページを見つけました。

しかし、おそらくSOの誰かがこれを機能させる方法を知っていますか?

4

4 に答える 4

2

これは静的なライブラリであるため、(プラグインが自分自身を登録するのではなく)マネージャーにプラグインを登録させることを検討してください。ヘッダーファイルは、マネージャーがヘッダーのインクルードに基づいてプラグインを登録するかどうかを制御するpreprocシンボル(つまり、JPEG_PLUGIN)を定義できます。

#include "JpegPlugin.h"

void PluginManager :: RegisterPlugins()
{{
#idef JPEG_PLUGIN
    RegisterPlugin(&jpeg_instance);
#endif
}

JpegPlugin.hは、必ずしもJpegPluginの定義を含める必要はありません。これは次のようなものである可能性があります。

#ifndef JPEG_PLUGIN_HEADER
#define JPEG_PLUGIN_HEADER

#if 0 //プラグインを使用するには、これを1に変更します
#define JPEG_PLUGIN
#include "Jpeg_PluginCls.h"
#endif

#endif
于 2009-05-17T02:28:02.623 に答える
2

これがこの問題を解決した方法の解決策かどうかはわかりませんが、オブジェクトファクトリの静的登録で同様の問題が発生し、Visual Studioでは__declspec(dllexport)に関連するクラスを宣言することで解決しました。これは必要でした。関連するライブラリはdllではありませんでしたが。ただし、これがないと、リンカは参照されていないクラスを省略します。

私たちが取り組んだレジストリソリューションは少し異なり、Stackで割り当てられたオブジェクトは含まれていませんでした。CPPユニットから部品を持ち上げました。ここで、__declspecアプローチiircを発見しました。

[編集]#includeコードの一部から登録済みクラスの宣言も行う必要がありました。

于 2009-05-17T02:49:52.867 に答える
1

これは、HaraldScheirichの回答のフォローアップです。

いくつかの実験を行いましたが、MSVC ++ 2005のリリースモード(デバッグモードではない)/OPT:REFによってリンカーへのフラグがオンになり、LINKのドキュメントによると、参照されていないシンボルが最終的なEXEから削除されるようです。また、のWebページは__declspec(selectany)、グローバルオブジェクトのコンストラクターがオブジェクトへの参照とは見なされないことを示しているようです(誤ってIMHOですが、そこにあります)。だから私の推測では、この問題はデバッグビルドでは「なくなる」と思います-それは正しいですか?

__declspec(dllexport)したがって、Haraldの使用の提案は、ソースコード内で指定されているため、シンボルを「参照済み」としてマークする便利な方法だと思います。何らかの理由でシンボルのエクスポートを避けたい場合は、/INCLUDE:mysymbolリンカーフラグを使用するか、フラグをオフにすることで同じことを実行できると思います/OPT:REF

于 2009-05-17T10:15:57.023 に答える
0

お願いします:

  1. 静的libプロジェクトをexeプロジェクトへの参照として追加します
  2. 「リンクライブラリの依存関係」と「リンクライブラリの依存関係を入力として使用する」の両方をtrueに設定します。

これを参照してください: 構成

「リンクライブラリの依存関係を入力として使用する」が「はい」に設定されている場合、プロジェクトシステムは、依存プロジェクトによって生成された.libsの.objファイルにリンクします。したがって、すべてのシンボルが保持されます。

于 2016-10-26T16:40:26.547 に答える