0Pricing
C++ Academy · レッスン

extern CとC ABI

extern Cを使って、C++ライブラリからC互換インターフェースを公開します。

「extern CとC ABI」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

なぜ相互運用するのか

C++には、名前修飾、例外、テンプレートなどを含む複雑なABI(Application Binary Interface)があります。他の言語(C、Python、Rust)は、修飾されたC++シンボルを直接利用できません。

extern "C"

宣言をextern "C"で囲むと、C++の名前修飾を無効にし、Cの呼び出し規約を使用できます。

extern "C" {
    void greet(const char* name);
    int add(int a, int b);
}

なぜC ABIなのか

C ABIは、言語間で利用できる最も基本的な共通基盤です。ほぼすべての言語がFFIを通じてC関数を呼び出せます。

ヘッダーファイルのパターン

条件付きのextern "C"を使うと、CとC++の両方から使用できるヘッダーを作成できます。

#ifdef __cplusplus
extern "C" {
#endif

void hello(void);
int sum(int a, int b);

#ifdef __cplusplus
}
#endif

エクスポートできないもの

一部のC++機能には、Cに相当するものがありません。

  • クラス(Cにはクラスの概念がありません)
  • テンプレート(コンパイル時に解決されるため、エクスポートできません)
  • オーバーロードされた関数(名前修飾がないため、オーバーロードできません)
  • 例外(FFIの境界を越える前に捕捉する必要があります)

クラスを公開する

不透明ポインタとC形式のAPIの背後にクラスを隠します。

// header (C visible)
typedef struct Widget Widget;
Widget* widget_create(int x);
void    widget_destroy(Widget*);
int     widget_value(const Widget*);

// .cpp
class WidgetImpl { /* ... */ };
extern "C" {
    Widget* widget_create(int x) { return reinterpret_cast<Widget*>(new WidgetImpl(x)); }
    void widget_destroy(Widget* w) { delete reinterpret_cast<WidgetImpl*>(w); }
}

FFIを越える例外を避ける

C経由で呼び出されたC++関数から例外が送出されると、異常終了します。境界で捕捉してください。

extern "C" int safe_call() {
    try {
        risky();
        return 0;
    } catch (...) {
        return -1;
    }
}

メモリの所有権

何を誰が所有するのかを文書化します。通常は、割り当てた側が解放します。所有権の不一致は、メモリリークや二重解放につながります。

FFIを越える文字列

std::stringはC++専用です。FFIではconst char*として渡します。受け取る側がコピーするかどうかを決め、ライフタイムを文書化してください。

FFIを越える構造体

CとC++で同じレイアウトになるPOD(plain old data)構造体を使用します。仮想関数、参照、stdの型は避けてください。

コールバック

関数ポインタ(またはvoid*と関数ポインタの組み合わせ)をFFI経由で渡します。クロージャ用にコンテキストポインタを用意してください。

extern "C" {
    typedef void (*Callback)(int value, void* user_data);
    void register_callback(Callback cb, void* user_data);
}

リンケージとヘッダー

extern "C"が変更するのはリンケージだけで、動作ではありません。関数は内部ではC++としてコンパイルされますが、外部からはC関数として呼び出せます。

クイックチェック

他の言語に公開するとき、なぜC++関数をextern "C"で囲むのですか。

まとめ

extern "C"によって、関数はCリンケージを持つようになります。つまり、名前修飾がなく、Cの呼び出し規約を使用します。C++をFFI経由で他の言語に公開するには、これを使用します。クラスは不透明ポインタの背後に隠し、境界で例外を捕捉し、所有権を明確に文書化してください。

よくある質問

「extern CとC ABI」レッスンは無料ですか?

はい。「extern CとC ABI」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「extern CとC ABI」で何を学びますか?

extern Cを使って、C++ライブラリからC互換インターフェースを公開します。 ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「extern CとC ABI」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. extern CとC ABI
  2. pybind11でC++からPythonを呼び出す
  3. Rust FFI境界向けC++
  4. SWIGによる多言語バインディング
← C++ Academyに戻る