1
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 1 year has passed since last update.

CrystalでC言語のバインディングを自動生成する crystal_lib

Last updated at Posted at 2021-06-29

Crystal言語には、C言語のライブラリのバインディングを自動生成するツールが存在する。

追記:これをさらにラップした libgen というものがあるそうです。この記事ではlibgenは扱いません。

crystal_lib の使い方は簡単で、

git clone https://github.com/crystal-lang/crystal_lib
cd crystal_lib
shards install
crystal build src/main.cr

として実行形式のファイルを作成する。

次に、examplesを参考にして作成したいライブラリのテンプレートを作る。いくつかexampleを貼ります。こんな感じ。

lib_event.cr
@[Include("event.h", prefix: %w(event_ EVENT_ Event))]
@[Link("event")]
lib LibEvent
end
lib_git2.cr
@[Include(
  "git2.h",
  prefix: %w(git_ GIT_ Git),
  import_docstrings: "brief",
)]
@[Link("git2")]
lib LibGit2
end
lib_ruby.cr
@[Include(
  "ruby/st.h",
  "ruby/ruby.h",
  prefix: %w(rb_ ruby_),
  remove_prefix: false,
)]
@[Link("ruby")]
lib LibRuby
end

prefixの指定ができるが、それ以外に自分でfunctionを記述することもできるようだ。

libc.cr
@[Include(
  "stdlib.h",
  "sys/types.h",
  "sys/socket.h",
  "netinet/tcp.h",
  "arpa/inet.h",
  "netdb.h",
  "string.h",
  "stdio.h",
  "unistd.h",
  "sys/file.h",
  "dirent.h",
  "sys/stat.h",
  "glob.h",
  flags: "-Dlint",
)]
lib LibC
  AF_UNSPEC = AF_UNSPEC
  AF_UNIX   = AF_UNIX
  AF_INET   = AF_INET
  AF_INET6  = AF_INET6

  SOL_SOCKET    = SOL_SOCKET
  SO_REUSEADDR  = SO_REUSEADDR
  SO_KEEPALIVE  = SO_KEEPALIVE
  SO_LINGER     = SO_LINGER
  SO_SNDBUF     = SO_SNDBUF
  SO_RCVBUF     = SO_RCVBUF
  TCP_NODELAY   = TCP_KEEPALIVE
  TCP_KEEPIDLE  = TCP_KEEPALIVE
  TCP_KEEPINTVL = TCP_KEEPINTVL
  TCP_KEEPCNT   = TCP_KEEPCNT

  # memory
  fun malloc
  fun free

  # socket
  fun freeaddrinfo
  fun gai_strerror
  fun getaddrinfo
  fun socket
  fun socketpair
  fun inet_pton
  fun inet_ntop
  fun htons
  fun bind
  fun listen
  fun accept
  fun connect
  fun gethostbyname
  fun getsockname
  fun getpeername
  fun getsockopt
  fun setsockopt
  fun shutdown

  # string
  fun atof
  fun strtof
  fun strlen
  fun snprintf

  # file
  F_OK = F_OK
  X_OK = X_OK
  W_OK = W_OK
  R_OK = R_OK

  fun access
  fun link
  fun rename
  fun symlink
  fun unlink
  fun flock

  # dir
  fun getcwd
  fun chdir
  fun opendir
  fun closedir
  fun mkdir
  fun rmdir
  fun readdir
  fun rewinddir
  fun glob
  fun globfree

  # env
  # $environ : Void
  fun getenv
  fun setenv
  fun unsetenv
end

テンプレートを作成し終わったら、先程生成した実行形式のファイルで読み込む。アウトプットは標準出力なので適宜保存する。

./main examples/lib_git2.cr > libgit2.cr

このバインディング自動生成機能だが、当然完璧ではない。
私の観測した範囲では

  • bitfields はうまく変換されない
  • alias と type を複数回定義する

のようなことがあった。細かい欠点はともあれ、Crystal言語製作者謹製のライブラリであり、非常に便利であることは間違いないと思います。

この記事は以上です。

1
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
1
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?