今月Swiftがオープンソースとして公開されました。何か試したかったのでC言語とのリンクをと思ったのですが、少し踏み込んでHaskellにしてみました。
環境: swift-2.2-SNAPSHOT-2015-12-22-a-ubuntu15.10.tar.gz / Ubuntu 15.10
Swiftインストール:
https://swift.org/download/#latest-development-snapshots
からダウンロードした上記ファイルを解凍して、usr/binにパスを通します。
usr/lib/swift/linuxにある、libswiftCore.soをLinuxの/usr/local/libにコピーします。
とりあえず簡単なテストをするだけなので、これだけにしました。
export PATH:~/swift/usr/bin
sudo cp libswiftCore.so /usr/local/lib
sudo ldconfig
Haskellインストール:
sudo apt-get install ghc
fib.hs
module Fib where
import Foreign.C.Types
fibonacci :: Int -> Int
fibonacci n = fibs !! n
where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
fibonacci_hs :: CInt -> CInt
fibonacci_hs = fromIntegral . fibonacci . fromIntegral
foreign export ccall fibonacci_hs :: CInt -> CInt
参考: https://wiki.haskell.org/Calling_Haskell_from_C
このコードをそのまま使い、Swiftから呼び出してみます。
fibsw.swift
import Foundation
hs_start()
var a: CInt = 12
let fb = fibonacci_hs(a)
print("fibonacci \(a) : \(fb)")
hs_end()
なんとダイレクトで呼び出せてしまいます。しかし、初期化処理とか必要になってくるので、Cのグルーコードを用意します。
fibc.h
#include "fib_stub.h" int hs_start(); int hs_end();
fibc.c
#include <stdio.h>
#include "fibc.h"
int hs_start()
{
int argc = 2;
char *argv[] = {"+RTS", "-A32m", NULL};
char **pargv = argv;
hs_init(&argc, &pargv);
return 0;
}
int hs_end()
{
hs_exit();
return 0;
}
fib_stub.hは、Haskellコンパイル時に自動生成されます。
#include "HsFFI.h"
#ifdef __cplusplus
extern "C" {
#endif
extern HsInt32 fibonacci_hs(HsInt32 a1);
#ifdef __cplusplus
}
#endif
ビルド:
ghc -c -O fib.hs
cc -c -o fibc.o fibc.c -I/usr/lib/ghc/include
swiftc -c -o fibsw.o fibsw.swift -import-objc-header fibc.h -I/usr/lib/ghc/include
ghc –make -no-hs-main fibsw.o fibc.o fib.o -o fibsw -lswiftCore
実行結果:

SwiftがLinuxで手軽に使えると、サーバ、クライアントともSwiftで開発ができるのでいろいろと便利かもしれません。
Perfect.orgなども要注目ですね。