背景
C/C++ メインのグラフィックスアプリやグラフィックスライブラリがある.
スクリプト系言語でバインディングを書きたい. UI を作りたいとか, ユニットテストとかでパラメータをいじったりをスクリプト側で行いたいなど.
元々グラフィックス用向けを想定して開発されていたらしい vlang を使ってみる.
hot code reloading とか, graphics 周りに強いのをアピール(W.I.P だが)しています.
vlang について
OpenGL binding とかが標準であります. go ライクで型付きで, gc が無いので素晴らしいですね.
(gc なしにいろいろうまく処理するのはまだ作業途中ですが)
基本 C compiler(gcc とか)に丸投げっぽい感じで処理していて, 本体は軽くてよい(LLVM とかつかっていない)
vlang 自体が C に変換してコンパイルして実行してる(はず)ので, C との親和性は高いと想像します.
C 関数を呼ぶ
Windows を含む cross platform を謳っていますが, ここでは Linux 環境を想定します.
C/C++ ユーザーからすれば, 比較的すんなり理解できると思います.
複雑な struct は難しいかもしれませんので, C レイヤーのほうで完結なデータ構造にしておくのが吉です.
# pragma once
# ifdef __cplusplus
extern "C" {
# endif
int myfunc(int x, int y);
# ifdef __cplusplus
}
# endif
こんなかんじでヘッダーを用意して,
# include "mylib.h"
int myfunc(int y, int x)
{
return x + y;
}
こんな感じで実体を書いて,
$ gcc -o libmylib.so -shared -c mylib.cc
とコンパイルして,
// test.v
# flag -I.
# flag -L.
# flag -lmylib
# include "mylib.h"
fn C.myfunc(x int, y int) int
fn main() {
n := C.myfunc(3, 4)
println(n)
}
$ ../v run test.v
7
voala!
エラーが出る場合は,
$ v -show_c_cmd test.v
==========
cc -std=gnu11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unused-function -Wno-missing-braces -Wno-unused-label -Werror=implicit-function-declaration -o "/home/syoyo/work/v/sandbox/test" "/home/syoyo/.cache/v/test.tmp.c" -I "/home/syoyo/work/v/sandbox" -L "/home/syoyo/work/v/sandbox" -lmylib -lm -lpthread -ldl
cc took 916 ms
=========
として, どのように内部でリンクなどの呼び出しが行われれているか確認できます!
Windows(llvm-mingw) で動かす.
llvm-mingw と組み合わせてみます.
とりあえず llvm-mingw だと, MSVC と同様に, import lib を作らないとリンクできないことがわかりました.
/d/local/llvm-mingw/bin/gcc -shared -o mylib.dll mylib.cc -Wl,--output-def,foo.def
/d/local/llvm-mingw/bin/llvm-dlltool -m i386:x86-64 -d foo.def -l foo.lib -D mylib.dll
という風にすればいけます!
最近の llvm-dlltool ですと, -D
で dll ファイル指定も必要でした.
./v.exe -g -show_c_cmd -cc /d/local/llvm-mingw/bin/gcc.exe run test.v
==========
D:/local/llvm-mingw/bin/gcc.exe -std=gnu11 -Wall -Wextra -Wno-unused-variable -Wno-unused-parameter -Wno-unused-result -Wno-unused-function -Wno-missing-braces -Wno-unused-label -g3 -no-pie -Werror=implicit-function-declaration -o "test.exe" "C:\Users\syoyo\AppData\Local\Temp\v\test.tmp.c" -municode -ldbghelp -I "C:\Users\syoyo\local\v_windows" -L "C:\Users\syoyo\local\v_windows" -lmylib
=========
7
Voala!
TODO
- C コードに, dllimport, dllexport も記載しておくとよいか?
- import lib 作成用の .def を別コマンドで行う(.dll から抜き出す方法を調べる)
まとめ
なんだかいい感じに C と連携できそうなので, Patoreon で vlang プロジェクト(実質的にはひとりで開発している?)に課金したくなってきますね!