extern宣言 — 外部関数の呼び出し

学習目標: extern "C" を使ってC/C++/システムの関数をCm内から呼び出す方法を学びます。
所要時間: 15分
難易度: 🟡 中級〜上級


基本構文

extern "C" 戻り値型 関数名(引数...);

例: 数学関数

extern "C" double sin(double x);
extern "C" double cos(double x);
extern "C" double sqrt(double x);

int main() {
    double angle = 3.14159 / 4.0;
    double s = sin(angle);
    double c = cos(angle);
    println("sin={s}, cos={c}");
    return 0;
}

戻り値型のパターン

スカラ型

extern "C" int    my_add(int a, int b);
extern "C" double my_sqrt(double x);
extern "C" long   my_hash(string s);
extern "C" bool   my_check(int x);
extern "C" void   my_init();

文字列

// Cmの string は内部的に char* として扱われる
extern "C" string my_greet(string name);

ポインタ

extern "C" void* malloc(int size);
extern "C" void free(void* ptr);
extern "C" int* create_array(int n);

ハンドルパターン

Cmの標準ライブラリで広く使われるパターンです。
C++のオブジェクトを long ハンドルとして保持します。

Cm側

// C++のリソースをlongハンドルで管理
extern "C" long resource_create(int size);
extern "C" int resource_read(long handle);
extern "C" void resource_destroy(long handle);

int main() {
    long r = resource_create(1024);
    int data = resource_read(r);
    resource_destroy(r);
    return 0;
}

C++側

#include <cstdlib>

struct Resource {
    int* data;
    int size;
};

extern "C" {

long resource_create(int size) {
    auto* r = new Resource();
    r->data = (int*)calloc(size, sizeof(int));
    r->size = size;
    return (long)r;
}

int resource_read(long handle) {
    auto* r = (Resource*)handle;
    return r->data[0];
}

void resource_destroy(long handle) {
    auto* r = (Resource*)handle;
    free(r->data);
    delete r;
}

}

use libc との違い

方法 用途 宣言
extern "C" 自作C/C++関数、任意のライブラリ 型シグネチャを明示
use libc { ... } 標準Cライブラリ (malloc, memcpy等) 名前のみ
// extern "C" — 型を明示
extern "C" void* malloc(int size);

// use libc — 名前のみ(型は暗黙)
use libc { malloc, free, memcpy }

ビルド方法

自作のC/C++コードとリンクする場合:

# C++をコンパイル
g++ -c my_runtime.cpp -o my_runtime.o

# Cmからリンク
cm compile main.cm my_runtime.o -o main

Objective-C++ (macOS):

# .mmファイルをコンパイル
clang++ -ObjC++ -c gpu_runtime.mm -o gpu_runtime.o -framework Metal

# Cmからリンク
cm compile main.cm gpu_runtime.o -o main -framework Metal

注意事項


次のステップ


最終更新: 2026-02-08