SWIG (Simplified Wrapper and Interface Generator) は、C/C++プログラムの関数やクラスをPython、Ruby、Javaなど他のプログラミング言語から利用可能にするツールです。本ハンドブックでは、SWIGの基本概念、インターフェースファイルの作成方法、各言語バインディングの具体例について説明します。

対象読者

編集
  • C/C++プログラムを外部言語から利用したい開発者
  • SWIGを使用してマルチ言語対応のライブラリを作成したい方
  • ライブラリ開発やAPI設計に興味があるプログラマー

目次

編集
  1. SWIGとは
  2. SWIGのインストール
  3. 基本的な使い方
  4. インターフェースファイルの記述
  5. Pythonバインディングの例
  6. Javaバインディングの例
  7. 高度な設定
  8. 演習問題
  9. 参考文献

SWIGとは

編集

SWIGは、以下のような特徴を持つツールです:

  • 多言語対応: Python、Ruby、Java、C#、Perlなど、多数のプログラミング言語をサポート。
  • 自動コード生成: バインディングコードを自動生成し、手作業の工数を削減。
  • 柔軟なインターフェース定義: インターフェースファイルを使用して、エクスポートする関数やクラスを指定。

SWIGのインストール

編集

必要なソフトウェア

編集

SWIGの使用には以下のソフトウェアが必要です:

  • SWIG本体
  • C/C++コンパイラ(GCCやClangなど)
  • 対応言語の開発環境(例: Pythonの場合はPythonインタプリタ)

インストール手順

編集

Ubuntuの場合

編集
# apt update
# apt install swig

FreeBSDの場合

編集
# pkg install swig

ソースからインストール

編集

最新バージョンが必要な場合はソースコードからビルドします:

$ wget https://prdownloads.sourceforge.net/swig/swig-4.1.1.tar.gz
$ tar -xzf swig-4.1.1.tar.gz
$ cd swig-4.1.1
$ ./configure
$ make
# make install

基本的な使い方

編集

SWIGによるPythonバインディング

編集

以下は、SWIGを使用してC関数をPythonから呼び出す例です。

Cコード

編集
example.c
#include <math.h>

double square(double x) {
    return x * x;
}

インターフェースファイル

編集
example.i
%module example
%{
#include "example.c"
%}

double square(double x);

コマンドでの実行

編集
$ swig -python example.i
$ cc -shared -fPIC -I/usr/include/python3.11 -o _example.so example.c example_wrap.c

Pythonスクリプト

編集
import example

print(example.square(3.0))  # 出力: 9.0

インターフェースファイルの記述

編集

基本構造

編集

SWIGのインターフェースファイルには以下の要素が含まれます:

  • %moduleディレクティブ: モジュール名を指定
  • %{ ... %}: C/C++コードの直接挿入
  • 関数やクラスの宣言

例: クラスのエクスポート

編集
example.i
%module example
%{
#include "example.h"
%}

class MyClass {
public:
    MyClass(int value);
    int get_value();
    void set_value(int value);
};

Pythonバインディングの例

編集

SWIGでPythonバインディングを作成する際には、Python特有のディレクティブや型変換を指定できます。

文字列の変換

編集
example.i
%module example

%apply char * {const char *input};
%inline %{
const char* greet(const char *name) {
    static char buffer[256];
    snprintf(buffer, sizeof(buffer), "Hello, %s!", name);
    return buffer;
}
%}

Javaバインディングの例

編集

SWIGでJavaバインディングを生成する方法の例です。

インターフェースファイル

編集
example.i
%module example
%{
#include "example.h"
%}

%include "example.h"

SWIGコマンド

編集
$ swig -java example.i
$ javac example.java

高度な設定

編集
  • ディレクティブ: %feature%includeを活用してカスタマイズ可能。
  • 型マッピング: C++標準ライブラリの型をPythonのリストや辞書にマッピング。

演習問題

編集

問題1: 簡単な数学関数

編集

Cで作成した三角関数ライブラリをPythonから利用できるようにしてください。

問題2: クラスのエクスポート

編集

C++で作成したクラスをJavaから利用可能にしてください。

参考文献

編集