rabbit-slide-kou-rubykaigi-2016 2016.9.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rabbit +1 -0
- data/README.rd +24 -0
- data/Rakefile +17 -0
- data/a.md +48 -0
- data/config.yaml +23 -0
- data/how-to-create-bindings-2016.rab +421 -0
- data/images/bindings.svg +790 -0
- data/images/clear-code-silver-sponsor.png +0 -0
- data/images/extension-library-and-bindings.svg +219 -0
- data/images/libffi-and-bindings.svg +388 -0
- data/overview.md +51 -0
- data/pdf/rubykaigi-2016-how-to-create-bindings-2016.pdf +0 -0
- data/theme.rb +1 -0
- metadata +86 -0
data/overview.md
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# How to create bindings 2016 - 概要
|
2
|
+
|
3
|
+
バインディングとはRuby以外の言語(主にC言語とC++言語)で実装された機能をRubyで使うためのライブラリーです。バインディングを使うと、Rubyでその機能を実装しなくてもその機能を使えるようになるため、短時間で高品質の機能が手に入(ることがあ)ります。また、C言語での実装はRubyでの実装よりも10倍100倍速いことがざらにあるので、性能面でも有利です。画像処理・動画処理・音声処理・全文検索・機械学習・統計処理・暗号処理などは実装コスト・性能の両面からバインディングを利用して既存実装を活用するのが向いている分野です。
|
4
|
+
|
5
|
+
というような背景があり、RubyをWebだけでなく様々な分野で活用するためにはバインディングは重要です。そんなバインディングの作り方を紹介します。
|
6
|
+
|
7
|
+
## 拡張ライブラリーとしてバインディングを作る方法
|
8
|
+
|
9
|
+
バインディングを作るために使える仕組みが拡張ライブラリーです。拡張ライブラリーはC言語で実装された機能をRubyに組み込む仕組みです。C言語で既存の機能をラップする拡張ライブラリーを作ることでバインディングになります。
|
10
|
+
|
11
|
+
拡張ライブラリーの難点の1つに「インストールするためにはCコンパイラーが必要なこと」があります。拡張ライブラリーを使うためにはコンパイルする必要があるため、Cコンパイラーがないと拡張ライブラリーを使えません。GNU/LinuxやBSD系などCコンパイラーを用意しやすいOSもあればそうでないOSもあります。たとえば、WindowsではCコンパイラーを用意することの敷居が高く、インストールが難しいです。
|
12
|
+
|
13
|
+
この問題を解決する方法としてfat gemというやり方があります。これはgemの中にビルド済みバイナリーを入れるというやり方です。こうすることにより、ユーザーの環境にCコンパイラーがなくても拡張ライブラリーを使えるようになります。fat gemはWindowsユーザー向けだけに用意すればよいです。Windows以外のよく使われている環境ではCコンパイラーを用意することは比較的簡単だからです。
|
14
|
+
|
15
|
+
拡張ライブラリーの難点はもう1つあります。バインディング対象の機能数に応じて実装コストがあがる点です。Rubyが拡張ライブラリー用に提供しているAPIは比較的使いやすいため、拡張ライブラリーとしてバインディングを作ることは技術的にそれほど難しくありません。ただし、対象機能を1つずつラップするため、対象機能が多いとその分手間がかかるのです。
|
16
|
+
|
17
|
+
この難点を解決する方法としてバインディングを生成する方法があります。拡張ライブラリーによるバインディングの実装にはある程度パターンがあるので生成することができるのです。[SWIG](http://www.swig.org/)というツールはそれを実現するためのツールです。
|
18
|
+
|
19
|
+
## SWIGを使って拡張ライブラリー用のコードを生成してバインディングを作る方法
|
20
|
+
|
21
|
+
SWIGを使うと(多くの場合は)少ない記述でバインディング用の拡張ライブラリーのコードを生成できます。これで、少ない手間でたくさんの機能のバインディングを作ることができます。ただ、SWIGを使った場合でもいくつか難点があります。
|
22
|
+
|
23
|
+
SWIGも拡張ライブラリーを使ったバインディングなのでインストールが難しい問題があります。この問題をfat gemというやり方で解決できるのは前述のとおりです。しかし、SWIGを使った場合は別の問題もあります。インストール時にCコンパイラーとSWIGが必要になる点です。通常、SWIGはシステムにインストールされていないので別途インストールする必要があります。インストール時にSWIGを必要なくする方法があります。SWIGで生成した拡張ライブラリーのコードをgemに含める方法です。こうすることでインストール時にSWIGは必要なくなります。ただし、gemに含めたときに生成した機能しか含まれません。gemに含めたときの対象ライブラリーはバージョン1で、ユーザーがインストールしようとしたときはバージョン2になっていた、という場合、バージョン2で追加された機能は使えない、ということです。
|
24
|
+
|
25
|
+
性能面でも幾分オーバーヘッドがあります。手書きでシンプルに実装したバインディングとSWIGで自動生成したバインディングではシンプルに実装したバインディングの方が高速です。バインディングのメソッドを大量に呼び出す(何万回とか)場合は影響があるでしょう。
|
26
|
+
|
27
|
+
これまでのバインディングの作成方法ではインストールの難しさが難点としてでていました。これはC言語を使っていることが原因です。つまり、C言語を使わずにバインディングを作れればインストールが簡単になります。その方法はFFI(Foreign Function Interface)を使う方法です。
|
28
|
+
|
29
|
+
## FFIを使ってバインディングを作る方法
|
30
|
+
|
31
|
+
一般的にはFFIはバインディングを作るAPIすべてを指しますが、RubyではあまりFFIという用語を使いません。使っているのはlibffiというライブラリーを使ってRubyでバインディングを書けるAPIを提供しているRuby FFIだけでしょう。なお、Ruby本体にFiddleという同様の機能を提供するライブラリーがバンドルされていますが、こちらはFFIと呼ばれていません。
|
32
|
+
|
33
|
+
FFIを使うとRubyでバインディングを書くことができます。拡張ライブラリーでやっていたことをRubyで書けるようになっただけで、1つずつ機能をラップしていかなければいけない点は変わりませんが、それをCではなくRubyで書けるようになることで書きやすくなっています。
|
34
|
+
|
35
|
+
バインディングにC言語を使わなくなったことによりバインディングのインストールは確かに簡単になるのですが、バインディングが動くためにはラップ対象のライブラリーは依然として必要です。そのため、Windowsユーザーがインストールしにくいという点はそれほど解決されていません。
|
36
|
+
|
37
|
+
また、バインディングを書く言語がCからRubyになっているので手間は減ってはいますが、対象の機能がたくさんあると結局手間なのは変わりません。
|
38
|
+
|
39
|
+
なお、FFIを使うとSWIGを使ったときよりも性能が落ちます。
|
40
|
+
|
41
|
+
SWIGが拡張ライブラリーのコードを生成するように、対象ライブラリーの情報を元にFFIを使ったバインディングを生成する方法があります。それがGObject Introspectionというライブラリーを使う方法です。
|
42
|
+
|
43
|
+
## GObject Introspectionを使ってバインディングを作る方法
|
44
|
+
|
45
|
+
GObject Introspectionを使うと実行時に対象ライブラリーの情報を使ってバインディングを作成できます。古いバージョンと新しいバージョンを同時にサポートするというSWIGではインストールの難易度が上がるために難しかったことを容易に実現できます。
|
46
|
+
|
47
|
+
対象ライブラリーをgemに含めなければインストールが難しいという点はFFIを使ったバインディングと同じです。ただし、対象ライブラリーもgemに含める実装がRuby-GNOME2プロジェクト内にあるため、これを活用することで対象ライブラリーも含んだfat gemを提供できます。
|
48
|
+
|
49
|
+
GObject IntrospectionはRubyだけで使えるライブラリーではなく、PythonやJavaScriptなど他の言語でも使えるライブラリーです。これは、対象ライブラリーがGObject Introspectionをサポートしていればいろんな言語のバインディングがすぐに用意できるということです。これまで、バインディングは各言語ごとにそれぞれがんばって作成するものでしたが、GObject Introspectionベースにすることにより他の言語のユーザーと協力してバインディングを作成することができます。
|
50
|
+
|
51
|
+
以上のように、バインディング作成コスト(自動生成ベース+他言語ユーザーと協力でコスト削減)とインストールの容易さという観点からGObject Introspectionを使ったバインディングの作り方が魅力的です。しかし、難点もあります。それは、(現時点ではまだ)遅いこととGObject Introspection対応ライブラリーは限られているという点です。
|
Binary file
|
data/theme.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
include_theme("clear-code")
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rabbit-slide-kou-rubykaigi-2016
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2016.9.8.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kouhei Sutou
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rabbit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 2.0.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 2.0.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rabbit-theme-clear-code
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: This talk describes how to create Ruby bindings of a C library. It's
|
42
|
+
the latest information in 2016.
|
43
|
+
email:
|
44
|
+
- kou@clear-code.com
|
45
|
+
executables: []
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".rabbit"
|
50
|
+
- README.rd
|
51
|
+
- Rakefile
|
52
|
+
- a.md
|
53
|
+
- config.yaml
|
54
|
+
- how-to-create-bindings-2016.rab
|
55
|
+
- images/bindings.svg
|
56
|
+
- images/clear-code-silver-sponsor.png
|
57
|
+
- images/extension-library-and-bindings.svg
|
58
|
+
- images/libffi-and-bindings.svg
|
59
|
+
- overview.md
|
60
|
+
- pdf/rubykaigi-2016-how-to-create-bindings-2016.pdf
|
61
|
+
- theme.rb
|
62
|
+
homepage: http://slide.rabbit-shocker.org/authors/kou/rubykaigi-2016/
|
63
|
+
licenses:
|
64
|
+
- CC BY-SA 4.0
|
65
|
+
metadata: {}
|
66
|
+
post_install_message:
|
67
|
+
rdoc_options: []
|
68
|
+
require_paths:
|
69
|
+
- lib
|
70
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '0'
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
requirements: []
|
81
|
+
rubyforge_project:
|
82
|
+
rubygems_version: 2.5.1
|
83
|
+
signing_key:
|
84
|
+
specification_version: 4
|
85
|
+
summary: How to create bindings 2016
|
86
|
+
test_files: []
|