vlang コードを .so ビルドし, C/C++ などから呼べるようにする(println や builtin 関数いくつか動くのを確認).
背景
vlang の関数を, C から呼びたい
- vlang でプロトタイピングして動作確認したのち, C/C++ に組み込みたい
- vlang で live coding して動作確認したのち, リリース向けでは C/C++ バイナリ単体にしたい
など.
vlang 自体は, 一度 C コードに変換して実行しているため, C/C++ と連携はやりやすいと想像できます.
とりあえず基本的なコードは動きました.
環境
v 0.2 を仮定します(2020/03/31 時点ではまだリリースはされていない. git master
branch 利用)
Linux 64bit を仮定します.
0.2 から, モジュールのビルド方法が変わりました. ast パーサなど内部構造を変えたからでしょうか. より汎用的に使えるようになっています.
Of course.
— The V Programming Language (@v_language) March 29, 2020
module mymodule
fn sayhello() { ... }
v -o mymodule.c mymodule.v
cc -c mymodule.c
// main.c
void mymodule_sayhello();
int main() {
mymodule_sayhello();
}
cc main.c mymodule.o
モジュールをコンパイルする.
通常の C コードと同様な感じでモジュールを作ることができます.
- .v から .c を生成する
- C compiler で .so にコンパイルする
// fibrec.v
module fibrec
pub fn fib(n int) int {
if n <= 2 {
return 1
} else {
return fib(n-1) + fib(n-2)
}
}
$ ./v -shared -o mymodule.c fibrec/fibrec.v
-shared
を付けて, main 関数などが生成されないようにします.
あとは通常の C と同じように扱います.
-fPIC
は基本付けておきましょう. 付けないと一部 vlang 関数のコンパイルでうまくいかないです. -lm
など必要なライブラリもリンクしておきます.
これで完成です!
python から呼んでみます.
import ctypes
lib = ctypes.cdll.LoadLibrary("./fibrec.so")
arg_int = ctypes.c_int(10)
res = lib.fibrec__fib(arg_int)
print(res)
という感じで python から呼んで試してみましょう!
少なくとも, fibrec に println
や組み込み関数の array を追加して, うまく扱えるのを確認しました.
TODO
-
複数
.v
をコンパイルして.so
が作れるか確認する - ほかの vlang 組み込み関数がコンパイルできるか確認する
以下は, 古い情報です. 記録まで.
===============================================================
環境
v 0.1.25 を仮定します(2020/02/26)
Linux 64bit を仮定します.
Exporting function to library (dll/so) #2379
https://github.com/vlang/v/issues/2379
は, このままではうまくいきません.
module
まず, 普通に .v
を -shared
でビルドすると, main 関数など全部入りになります.
vlang では, module の機能(Java 的な感じ?)がありますので, module の機能を使います.
// fibrec.v
module fibrec
pub fn fib(n int) int {
if n <= 2 {
return 1
} else {
return fib(n-1) + fib(n-2)
}
}
フォルダの構成としては, <module>/file.v
が想定されます((Java 的な感じ? golang も同等かしら?). フォルダ名をモジュールと合わせる必要がありますが, 実態のコードがあるファイル名は .v
であればなんでもいいかもしれません.
$ mkdir fibrec
$ mv fibrec.v fibrec/
./v build module fibrec
とすると, ~/.vmodules/
に .o ができます. パスは変更できないようです.
$ ./v -verbose
として, どのようなコマンドが呼ばれるか確認しましょう.
-shared
をつけると, relocatable(-fPIC
つき)な <module>.o
が生成されます.
$ gcc -o fibrec.so -shared ~/.vmodules/fibrec.o
として, .so を作ります. nm でシンボルを確認しておきます.
python から呼んでみます.
import ctypes
lib = ctypes.cdll.LoadLibrary("./fibrec.so")
arg_int = ctypes.c_int(10)
res = lib.fibrec__fib(arg_int)
print(res)
55 と表示されれば成功です!
制限
println
や配列など, builtin や vlib の機能を使うと, シンボルが見つからないエラーになります. vlib
のいくつかを .so に取り込む必要があるようですが, 現状 _wyp0
シンボルが重複するなどのエラーになります. より一般的に vlang のコードを .so にするにはまだ開発に時間かかりそうです.
TODO
- Windows(llvm-mingw など)でうまくいくか確認する
- vlang の標準ライブラリが使えるようにする
- vlang を, C/C++ に組み込んでスクリプト実行する(libv みたいなのが作れればいけるか?)
Author And Source
この問題について(vlang コードを .so ビルドし, C/C++ などから呼べるようにする(println や builtin 関数いくつか動くのを確認).), 我々は、より多くの情報をここで見つけました https://qiita.com/syoyo/items/52d6b720393a72b3b5d9著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .