今月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なども要注目ですね。