0

私はいくつかのモジュラーアプリケーションを書いていて、抽象クラスと(純粋な)仮想関数/インターフェースのようなメソッドを使用しようとしています。

だから私はいくつかの「インターフェース」を定義しました:

class first { 
public: 
  virtual ~first() {}; 
  virtual void first_method() = 0;
};

class second { ... second_method() ... };

そして、これらを実装するクラス:

class TheObject : public BaseClass, public first, public second {
public: 
  void first_method();
  void second_method();
}

void TheObject::first_method() { do_something();} 
void TheObject::second_method() { do_something_better();} 

ところで、BaseClass にはいくつかの仮想 (ただし純粋ではない) メソッドもあります。

さて、dlopen や dlsym などをすべて実行したら、次のように (TheObject から) TheObject をプラグインに渡そうとします。

//In main app
pluginit(this);
// In plugin:
void pluginit (void * obj) {
    first * cls = (first*) obj;
    cls->first_method();  // FAIL!
}

// FAIL! の行で、プログラムは BaseClass の仮想メソッドに移動します。私はその理由を知っていると思います-コンパイル時にプラグインは最初に「インターフェース」のみを認識し、vtableがより多くの「インターフェース」で構成されていることを知りません。

問題は、このインターフェースを TheObject を知らないプラグインに正しく渡す方法です。何かのようなもの

new first : this; // typeof this = TheObject

ありがとうございました!

4

1 に答える 1

1

void ポインターへの変換は、魔法のように基本クラスを考慮しません。何かを void ポインターに変換した場合、それでできることは、元の型に戻すことだけです

したがって、これを行う必要があります:

derived * obj = new derived;
void * arg = static_cast<first *>(obj);      // upcast first!
f(arg);

// ... 

void f(void * p)
{
    first * obj = static_cast<first *>(p);   // all you know is that p
                                             // is a base pointer
    obj->foo();
}
于 2013-11-11T09:12:05.360 に答える