3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

vlang コードを .so ビルドし, C/C++ などから呼べるようにする(println や builtin 関数いくつか動くのを確認).

Last updated at Posted at 2020-02-26

背景

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 パーサなど内部構造を変えたからでしょうか. より汎用的に使えるようになっています.

モジュールをコンパイルする.

通常の 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 みたいなのが作れればいけるか?)
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?