SwiftとC++を手っ取り早く連携する方法【C言語にも対応】

C言語関数を用いれば簡単に連携が可能になります。Objective-C++を利用する方法もありますが、インターフェースが単純なものや、インスタンスの管理が不要な完結型の処理であればこちらの方法のほうが簡単で手っ取り早いです。

C++との連携

test.cpp

#include "test.hpp"
void test() { /* C++固有の処理 */ }

test.hpp

#ifdef __cplusplus
extern "C" { extern void test(); }
#endif

プロジェクト名-Bridging-Header.h

#include "test.hpp"

extern "C"を用いている所が肝です。ヘッダー側ではC++固有機能の利用やC++固有のデータ型の利用が出来ない点に注意してください(例えばstd::stringを戻り値にするようなことは出来ない。デフォルト引数も指定出来ない)。逆にC言語の文法で書かれた列挙体や構造体であれば普通にSwift間でのやり取りが可能になります。

Bridging-Header.h

上記のブリッジングヘッダープロジェクト名-Bridging-Header.hは予め作成しておいてください。作成したブリッジヘッダーのファイルパスは、以下のXcodeプロジェクト設定項目に指定することで有効になります。

Building Settings → Swift Compiler - Code Generation → Objective-C Bridging Header
>> "プロジェクト名/プロジェクト名-Bridging-Header.h"

設定は以上です。Swiftプロジェクトからtest()関数が使用できるようになります。

オブジェクトのやり取りや状態管理が必要な処理を書く際には従来通りObjective-C++を用いた方法を取ると良いでしょう。Objective-CのクラスでC++のオブジェクトをラップする方法などが知られています。

C言語との連携

C言語(*.c, *.h)の場合もObjective-C(*.m)を用いることなく連携が可能です。手順自体はC++の時と同じです。

// test.h
extern void test();
// test.c
void test() { /* C言語固有の処理 */ }
// プロジェクト名-Bridging-Header.h
#include "test.h"

備考

今回紹介した方法は意外と知られていないようです。

SwiftはC言語とのやり取りが出来るので、C++のソースでもC言語リンケージでのやり取りなら可能だろうという発想で実現されています。

ちなみに既存のC++ヘッダーファイルはBridging-Header側でそのまま読み込めます。その際extern "C"指定されていない宣言はきちんと無視されます。

連携の手段がC言語関数やPOD構造体のみに限られている所は難点ですが、既にC++とC言語間のラッパーを独自に作っているような開発者であれば、今回紹介した方法のほうが再利用性が高くオススメです。

広告