質問

最近私はThreadクラスライブラリを設計してきた、私が作った次のようなスレッド抽象クラスます:

class Thread {
public:
    run() { /*start the thread*/ }
    kill() { /*stop the thread*/ }
protected:
    virtual int doOperation(unsigned int, void *) = 0;
};

リアルタイムスレッドクラスは、この抽象クラスを継承し、独自のロジックでdoOperationメソッドを実装し、戦略のようなものでしょうパターンでます。

問題は、私は次の関数でスレッドを実行している定義Cバックエンドライブラリに頼ってるということです。

int startThread(char* name, (int)(*)(unsigned int, void*), int, int, int, void*);

あなたが見ることができるように。第2のパラメータは、スレッドのループへの関数ポインタ(メイン関数)であり、ここでは問題です。私はrun方法でスレッドを開始するには、このC-関数を使用するので、私は2番目のパラメータにdoOperationのアドレスを渡し、そしてこれは、型の不一致により、行うことができない。

私はポインタを返すためにreinterpret_castを使用しようとしましたが、私ISO-C ++は、初期化されていない関数メンバーのポインタを返す禁止します。 私は、静的メソッドを使用すると、私は推測する唯一のソリューションである、この対立を克服する方法がわからないが、それは私の設計パターンを吹く!

役に立ちましたか?

解決

まず、それは良い情報が含まれているとして、マイケル・バリが提供されるリンクを必ずお読みください。そこで、ここではそのためのC ++っぽい擬似コードがあります:

int wrapperDoOperation(int v, void *ctx)
{
    Thread *thread = (Thread *)ctx;
    return thread->doOperation(v);
}

class Thread {
public:
    run() {
         startThread("bla", wrapperDoOperation, bla, bla, bla, (void *)this);
    }
    kill() { /*stop the thread*/ }
protected:
    virtual int doOperation(unsigned int) = 0;

friend wrapperDoOperation ......;
};

アイデアはdoOperationは、スレッドのメンバ関数であること、ボイド*コンテキストを必要としないということです、あなたはちょうどあなたがオブジェクト自体のコンテキストとして渡すものは何でも続けることができます。そのため、あなたはdoOperationにactuallにこのポインタを渡すためにボイドポインタを使用することができます。無効*詳細はいいですが、あなたのクラスのユーザーから隠されていることに注意してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top