サンの実装している C と C++ の関数リンケージはバイナリ互換です。すべての C++ の実装がこうなっているわけではありませんが、比較的共通のことです。互換性がなくなってもかまわないのであれば、キャストを使って C++ リンケージ関数を C リンケージ関数と同じように使用できます。
たとえば静的メンバー関数がよい例です。リンケージに関する C++ 言語の新しい規則が関数の型の一部となるまでは、クラスの静的メンバー関数を C リンケージを持つ関数として扱うのが一般的でした。これによって、クラスメンバー関数のリンケージを宣言できないという制限を回避していました。たとえば、次の例を考えてみましょう。
// 既存のコード typedef int (*cfuncptr)(int); extern“C”void set_callback(cfuncptr); class T { ... static int memfunc(int); }; ... set_callback(T::memfunc); // 新しい規則では無効
上記の問題を解決するには、前の項でお勧めしたように T::memfunc を呼び出す関数ラッパーを作成してから、すべての set_callback 呼び出しを変更して T::memfunc の代りにラッパーを使用します。こうすると、完全な移植性を持つ正しいコードになります。
もう 1 つの解決策として、次の例のように多重定義した set_callback 呼び出しを作成して、C++ リンケージを持つ関数を受け取り、元の関数を呼び出すこともできます。
// 変更したコード extern“C”{ typedef int (*cfuncptr)(int); // C 関数へのポインタ void set_callback(cfuncptr); } typedef int (*cppfuncptr)(int); // C++ 関数へのポインタ inline void set_callback(cppfuncptr f) // 多重定義したもの { set_callback((cfuncptr)f); } class T { ... static int memfunc(int); }; ... set_callback(T::memfunc); // 元のコードと同じ
この例では、既存のコードをわずかに変更しただけです。ここには、コールバックを設定する set_callback を新たに追加しました。既存のコードは元の set_callback を呼び出していましたが、ここでは多重定義したものを呼び出し、それが元のものを呼び出します。多重定義したものはインライン関数なので、実行時のオーバーヘッドはまったくありません。
この方法は Sun C++ では動作しますが、すべての C++ の実装で動作するとは限りません。他のシステムでは、C 関数と C++ 関数の呼び出し順序が異なる場合があるからです。