2017-09-21 24 views
7

Haskell(GHC)で書かれたコードのコールバック関数を提供したいと思います。 GCC Cコンパイラのような関数型を使用して、関数をエクスポート/インポートし、実行時に自分のコードと相互運用できます。メンバー静的コールバック関数のextern "C"

Iが実際にクラスへthisポインタを受け入れ、ちょうどそのメソッドを呼び出すコールバック関数を提供しなければならない:

struct C 
{ 
    int f(int i) { ; } 
    static int f_callback(void * self, int i) 
    { 
     static_cast< C * >(self)->f(i); 
    } 
}; 

論理f_callbackクラスCの一部であるので、私は、対応するにそれを配置しました名前空間の範囲。

しかし、私はextern "C"言語仕様を使用する必要があります(呼び出し規約はここでは重要なマングリングではありません)。 extern "C"を明示的な名前空間で宣言して定義することは可能ですが、extern "C"関数の特別な規則がいくつか存在しますが、there isは単純な名前空間1との区別がありません。

static extern "C"関数をクラススコープに定義することはできますか?

+0

いいえ、IIRCできません。しかし、CとC++が異なるABIやスタックフレームを使用することを心配する必要はありません。 – user0042

+0

@ user0042 '静的な__cdecl'より安全で何もありませんか? – Orient

+0

これは移植性のない注釈ですが、使用できます。 – user0042

答えて

5

外部コールバックは、仕様上、特定のクラスにリンクされていません。

静的なクラスメンバを作成することは、コードの内部構造に応じてうまくいくかもしれませんが、現実を誤って表します。

したがって、それを独立したextern "C"関数にすることをお勧めします。これは、誤解を避け、仮定を強調する(例えば、自己はCであると仮定されるが、実際には他のものであり得る)。 f()が公開されている場合、これはすべて非常にきれいです。プライベートである場合は、コールバックを友人にする必要があります。このタイトなカップリングは再び強調表示されます。

ラッパーの代わりに、冗長な仲介人を追加するだけで、同じ結果が得られます。

関連する問題