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


Swiftから直接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++固有のデータ型のやり取りが出来ない点に注意してください。逆にC言語の文法で書かれた列挙体や構造体であれば普通に利用出来ます。

Bridging-Header.h

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

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

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

オブジェクトのやり取りや状態管理が必要な処理を書く際には従来通りObjective-C++を用いた方法を取ると良いでしょう。ObjCのクラスで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言語やObjCとのやり取りが出来るので、C++でもC言語リンケージでのやり取りなら可能だろうという発想で実現されています。既存のC++ヘッダーをそのまま読み込むだけでいいので非常に便利です。extern "C"指定されていない宣言はきちんと無視されます。

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

広告