2011-08-15 5 views
0

私はたくさんの(おそらく何百もの)異なるC++ファイルを持っています。各関数には10個の関数が含まれ、すべてがintとdoubleをとり、intを返します。特定のファイルから関数ポインタを取得する

したがって、これらのファイルのいずれかで、これらの機能の一つへのポインタは、次のようになります。

int (*foo)(int, double); 

そして私は、これらの関数ポインタの10を含むクラスを、持っています。

このクラスのコンストラクタにこれらのC++ファイルの1つのファイル名を取り込み、そのファイルの関数をポインタに入れ、後でその関数を使用できるようにすることはできますか?

異なるファイルの2つの関数が同じ名前を持っていても、複数のプログラマーが異なるファイルをリストに提出できるという考えがあり、10人の同じ名前を使用する可能性があることが望ましいでしょう。関数)が、それが不可能な場合、私はそれを避ける何かを把握することができます。

私が検索したところでは、関数を選択するときにファイルを区別することはできません。関数を1つのファイルに連結しても、指定しようとしても問題はありますこれらの関数はすべて同じ引数を持つため、選択する関数は10個です。

これを行う方法はありますか?私が考えていないよりよい解決策はありますか?

+0

機能を使うには、名前空間のファイルのための1つにまとめることができます。テンプレートを使用すると、指定された名前空間を使用してそれぞれのオブジェクトを作成できます。例を追加すると、私はそれをより詳細に説明しようとします。 – zabulus

答えて

1

これを実行する方法はありますか?私が だと思っているよりよい解決策はありますか?

私はそう考えると別の名前空間を使用できますか?私は自分の名前空間にある10個の機能の各グループを意味します。そうすれば、彼らはもはや衝突しないだろう。

それ以外のものは、dlsym + dlopenの奇妙なもの(またはそのwin32のもの)を試すことができます。それは私がやることではありません。

0

dynamic linking library(Linux-landではshared object)と書いてあります。

+0

あなたのコードは、実際にプラグインアーキテクチャを求めているようなものです。すべての関数を同じにして、各ファイルを.so/.dllにコンパイルし、実行時に* 1 *ダイナミックライブラリをロードし、名前から関数ポインタを取得します。 – Torp

0

文字通り聞いたことを実現するには、各C++ファイルをダイナミックライブラリに変換し、ライブラリコンストラクタでFILE文字列をキーとして静的宣言し、一部のグローバルマップに関数セットを登録し、make各ファイルには、イニシャライザが同じグローバルマップに関数の登録をトリガする静的変数がいくつかあることを確認してください。

プラグインを使用して同じ方法を実装するには、私が行ったことと似たようにすることができますhere(単にプラグインをダウンロードしてください、記事はまだ準備ができていません)。内容量:

  • app.cc - アプリケーション、すべてのプラグインライブラリをロードする
  • module.cc - ビジネスインタフェース module_ifc.hと "ロード可能" インターフェースbootstrap_ifc.hを実装するプラグインクラス
  • client.cc - bootstrap_ifc.hを実装し、モジュールの メソッドを使用するプラグイン。CCは、実行時に抽象ビジネスインタフェース(有用な部分、すべての機能)とブートストラップインタフェース(統一初期化部分を実装するクラスを持つことになり、関数の同じセットを持つ

あなたのCの各++ファイルを解決し、プラグインによって使用されますローダ)。このような各クラスは、クラスインスタンスのコンストラクタとデストラクタメソッドを宣言する別々の共有ライブラリに置かれます。

単純なクラスは、Linux上で共有ライブラリで動作します:異なるファイルから

#include <dlfcn.h> 

class library { 
    void* _handle; 
public: 
    library(char const* path); 
    ~library(); 

    template <typename F> F func(char const* name); 
}; 

library::library(char const* path) { 
    _handle = dlopen(path, RTLD_NOW); 
    if (!_handle) throw std::runtime_error(dlerror()); 
    std::clog << "opened library " << path << ", handle=" << std::hex << _handle << std::dec << "\n"; 
} 

library::~library() { 
    if (_handle) dlclose(_handle); 
    std::clog << "closed library, handle=" << std::hex << _handle << std::dec << "\n"; 
} 

template <typename F> F library::func(char const* name) { 
    dlerror(); 
    F func = reinterpret_cast<F>(dlsym(_handle, name)); 
    const char *dlsym_error = dlerror(); 
    if (dlsym_error) throw std::runtime_error(dlsym_error); 
    std::clog << "loaded symbol " << name << ", ptr=" << std::hex << ((void*)func) << std::dec << "\n"; 
    return func; 
} 
関連する問題