SwiftからC
Cの函数は,Swiftから直接呼び出せる。
だが,Swift blogにある通りSwiftのarrayのアドレスを直接渡せる。
自前のソース
Xcodeを使う場合
- Xcodeのプロジェクトを作成(例: foo)する。
- Command Line Toolを選ぶ。
- 言語はSwiftを選択。
- Cのソースを追加。ヘッダも一緒に作る。
- Bridging Headerをconfigureしてもらい,foo-Bridging-Headers.hに必要なソースを#include。
- モジュールはXCodeが作ってくれはる。
コマンドライン
オプション-import-objc-headerを使って名前を解決し,Swiftのソースをコンパイルする。推奨しないと断って,stackoverflowの質疑に書いてある。Xcode 6-Beta5からはSwiftコンパイラの名前がswiftcとなった。$ xcrun swiftc -c main.swift -import-objc-header addtwo.h $ clang -O2 -c addtwo.c $ xcrun swift main.o addtwo.o -o addtwo
Makefile
CC = /usr/bin/clang CFLAGS = -O3 SWIFT = /usr/bin/xcrun swiftc TARGET = addtwo OBJS = $(TARGET).o main.o HDRS = $(TARGET).h all : $(TARGET) $(TARGET) : $(OBJS) $(SWIFT) $^ -o $@ %.o : %.swift $(SWIFT) -c $< -import-objc-header $(HDRS) clean : rm $(TARGET) *.o
addtwo.c
#include "addtwo.h" double addtwo(double x, double y) { return x + y; }
Swift
var x = 1.0 var y: Double = 2.0 println(addtwo(x, y))CのdoubleはSwiftのCDoubleに対応するが,型推論を使っても,Doubleでも正しく動作する。変数は値渡し。
配列
double *はUnSafePointercsum.c
#include "csum.h" double csum(const double * x, long n) { double y = 0; for (int i = 0; i < n; i++) { y += x[i]; } return y; }
Swift
let v = [1.0, 2.0, 3.0] println(csum(v, v.count)) var w = [4.0, 5.0, 6.0] println(csum(&w, w.count))const double*にはletで定義した書き換え不可の配列やvarで定義した配列のアドレスが渡せる。
ライブラリ
外部のライブラリは,ライブラリとヘッダをプロジェクトに追加する。ちなみに共有ライブラリは次のように作る。$ clang -dynamiclib -Wl,-install_name パス オブジェクトファイル -o ライブラリ名.dylib
Framework
Accelerate.frameworkを使う。- Xcode左のNavigatorでプロジェクトファイルを選択。
- Build PhasesのLink Binary With Librariesの+をクリック。Accelerate.frameworkを追加。
- import Accelerate
- foo-Bridging-HeadersにAccelerate.hを#includeする必要はない。
Swift
import Accelerate let s1 = [1.0, 1.0, 2.0] let s2 = [1.0, 1.0, 0.5] println(cblas_ddot(CInt(s1.count), s1, 1, s2, 1))Accelerateは,XcodeプロジェクトだけでなくREPLでも同様にimportして使える。
コメント