rabbit-slide-kou-rubykaigi-2016 2016.9.8.0 → 2016.9.9.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 +4 -4
- data/Ruby bindings 2016.pdf +0 -0
- data/bindings-as-extension-library.rab +224 -0
- data/config.yaml +2 -2
- data/fat-gem.rab +165 -0
- data/how-to-create-bindings-2016.rab +192 -9
- data/images/bindings-as-extension-library.svg +208 -0
- data/images/bindings-by-ffi.svg +208 -0
- data/images/bindings-by-gobject-introspection.svg +499 -0
- data/images/bindings-by-swig.svg +273 -0
- data/images/maintain-gobject-introspection-based-bindings.svg +546 -0
- data/images/maintain-swig-based-bindings.svg +309 -0
- data/pdf/rubykaigi-2016-how-to-create-bindings-2016.pdf +0 -0
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ca44e98f9cccc78fb696c568d8e67915f3e25d16
|
4
|
+
data.tar.gz: 1526cd0e6cfb5cd2ea9316e095a42d892db32ec8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 117395c67a4666de8c3108d3815e2d2b418227c7e527b6f2a5cd15d1b293c1d35b443def0829b8bdef54a4d48debaf09a0e80102dbf1550508db60f64b58b047
|
7
|
+
data.tar.gz: e885d5309adbb94fde9d07d16ecc022c59eb6957165931d4dafdc0dd3a203e623027748ed9cac4ef5ea4781cc4aae607d1d02a47e7c7765468f303979cfc412d
|
Binary file
|
@@ -0,0 +1,224 @@
|
|
1
|
+
= Bindings as\nan extension library
|
2
|
+
|
3
|
+
: author
|
4
|
+
Kouhei Sutou
|
5
|
+
: institution
|
6
|
+
ClearCode Inc.
|
7
|
+
: content-source
|
8
|
+
RubyKaigi 2016
|
9
|
+
: date
|
10
|
+
2016-09-08
|
11
|
+
: allotted-time
|
12
|
+
5m
|
13
|
+
: theme
|
14
|
+
.
|
15
|
+
|
16
|
+
= How to create bindings\n(('note:バインディングの作り方'))
|
17
|
+
|
18
|
+
* Use C API provided by Ruby\n
|
19
|
+
(('note:Rubyが提供するC APIを使う'))
|
20
|
+
* (('wait'))It's for creating ext lib\n
|
21
|
+
(('note:拡張ライブラリーを作るためのAPI'))
|
22
|
+
|
23
|
+
= Define class\n(('note:クラス定義'))
|
24
|
+
|
25
|
+
# coderay c
|
26
|
+
#include <ruby.h>
|
27
|
+
void
|
28
|
+
Init_hello(void)
|
29
|
+
{
|
30
|
+
rb_define_class("Hello", rb_cObject);
|
31
|
+
/* Ruby: class Hello; end */
|
32
|
+
}
|
33
|
+
|
34
|
+
= Initialize\n(('note:初期化'))
|
35
|
+
|
36
|
+
# coderay c
|
37
|
+
#include <ruby.h>
|
38
|
+
void
|
39
|
+
Init_#{module_name}(void)
|
40
|
+
{
|
41
|
+
/* require "#{module_name}"
|
42
|
+
calls this function */
|
43
|
+
}
|
44
|
+
|
45
|
+
= Init example\n(('note:初期化例'))
|
46
|
+
|
47
|
+
# coderay c
|
48
|
+
#include <ruby.h>
|
49
|
+
void
|
50
|
+
Init_hello(void)
|
51
|
+
{
|
52
|
+
/* require "hello"
|
53
|
+
calls this function */
|
54
|
+
}
|
55
|
+
|
56
|
+
= Define method\n(('note:メソッド定義'))
|
57
|
+
|
58
|
+
# coderay c
|
59
|
+
static VALUE hello_to_s(VALUE self) {
|
60
|
+
return rb_str_new_cstr("Hello");
|
61
|
+
}
|
62
|
+
void Init_hello(void) {
|
63
|
+
VALUE hello;
|
64
|
+
hello = rb_define_class("Hello", rb_cObject);
|
65
|
+
rb_define_method(hello, "to_s", hello_to_s, 0);
|
66
|
+
}
|
67
|
+
|
68
|
+
= Build1\n(('note:ビルド1'))
|
69
|
+
|
70
|
+
# coderay ruby
|
71
|
+
# extconf.rb
|
72
|
+
require "mkmf"
|
73
|
+
# "hello" == "#{module_name}"
|
74
|
+
create_makefile("hello")
|
75
|
+
|
76
|
+
= Build2\n(('note:ビルド2'))
|
77
|
+
|
78
|
+
% ruby extconf.rb
|
79
|
+
% make
|
80
|
+
(hello.so is generated.)
|
81
|
+
|
82
|
+
= Use\n(('note:使う'))
|
83
|
+
|
84
|
+
% irb -I .
|
85
|
+
irb(main):001:0> require "hello"
|
86
|
+
=> true
|
87
|
+
irb(main):002:0> hello = Hello.new
|
88
|
+
=> #<Hello:0x00000001fd15a0>
|
89
|
+
irb(main):003:0> hello.to_s
|
90
|
+
=> "Hello"
|
91
|
+
|
92
|
+
= Create bindings\n(('note:バインディングを作る'))
|
93
|
+
|
94
|
+
* C API is for ext lib\n
|
95
|
+
(('note:C APIを使うと拡張ライブラリーを作れる'))
|
96
|
+
* (('wait'))C API is also for bindings\n
|
97
|
+
(('note:C APIを使うとバインディングも作れる'))
|
98
|
+
* (('wait'))Show it from now just FYI\n
|
99
|
+
(('note:参考までにこれから作り方を紹介する'))
|
100
|
+
|
101
|
+
= Bindings target\n(('note:バインディング対象'))
|
102
|
+
|
103
|
+
# coderay c
|
104
|
+
/* hello.h */
|
105
|
+
#pragma once
|
106
|
+
typedef struct hello_t Hello;
|
107
|
+
Hello *hello_new (void);
|
108
|
+
void hello_free (Hello *hello);
|
109
|
+
const char *hello_message(Hello *hello);
|
110
|
+
|
111
|
+
= Define class\n(('note:クラス定義'))
|
112
|
+
|
113
|
+
# coderay c
|
114
|
+
void
|
115
|
+
Init_hello(void)
|
116
|
+
{
|
117
|
+
VALUE hello;
|
118
|
+
/* Ruby: class Hello < Data; end */
|
119
|
+
hello = rb_define_class("Hello", rb_cData);
|
120
|
+
rb_define_alloc_func(hello, rb_hello_alloc);
|
121
|
+
}
|
122
|
+
|
123
|
+
= Wrap struct\n(('note:構造体をラップ'))
|
124
|
+
|
125
|
+
# coderay c
|
126
|
+
static VALUE
|
127
|
+
rb_hello_alloc(VALUE klass)
|
128
|
+
{
|
129
|
+
/* Allocate memory for wrapping
|
130
|
+
target struct in C (= Hello struct). */
|
131
|
+
return TypedData_Wrap_Struct(klass,
|
132
|
+
&rb_hello_type,
|
133
|
+
/* Target struct is NULL at this phase. */
|
134
|
+
NULL);
|
135
|
+
}
|
136
|
+
|
137
|
+
= Define type metadata\n(('note:型用のメタデータを定義'))
|
138
|
+
|
139
|
+
# coderay c
|
140
|
+
static const rb_data_type_t rb_hello_type = {
|
141
|
+
"Hello", /* Type name. */
|
142
|
+
/* Mark, free, size functions. */
|
143
|
+
{NULL, rb_hello_free, NULL,},
|
144
|
+
NULL, /* Parent. It must be NULL. */
|
145
|
+
NULL, /* Wrapped target struct. */
|
146
|
+
RUBY_TYPED_FREE_IMMEDIATELY,
|
147
|
+
};
|
148
|
+
|
149
|
+
= Free function\n(('note:メモリー解放関数'))
|
150
|
+
|
151
|
+
# coderay c
|
152
|
+
static void
|
153
|
+
rb_hello_free(void *data)
|
154
|
+
{
|
155
|
+
Hello *hello = data;
|
156
|
+
/* Just call the free function. */
|
157
|
+
hello_free(hello);
|
158
|
+
}
|
159
|
+
|
160
|
+
= Register (({initialize}))\n(('note:(({initialize}))登録'))
|
161
|
+
|
162
|
+
# coderay c
|
163
|
+
void Init_hello(void) {
|
164
|
+
/* VALUE hello = Hello class */
|
165
|
+
/* Ruby: def initialize; end */
|
166
|
+
rb_define_method(hello,
|
167
|
+
/* Name */ "initialize",
|
168
|
+
rb_hello_initialize,
|
169
|
+
/* No argument */ 0);
|
170
|
+
}
|
171
|
+
|
172
|
+
= Initialize\n(('note:初期化'))
|
173
|
+
|
174
|
+
# coderay c
|
175
|
+
static VALUE
|
176
|
+
rb_hello_initialize(VALUE self)
|
177
|
+
{
|
178
|
+
Hello *hello;
|
179
|
+
hello = hello_new(); /* Create a target */
|
180
|
+
DATA_PTR(self) = hello; /* Wrap the target */
|
181
|
+
return Qnil;
|
182
|
+
}
|
183
|
+
|
184
|
+
= Bind method\n(('note:メソッドをバインド'))
|
185
|
+
|
186
|
+
# coderay c
|
187
|
+
static VALUE rb_hello_message(VALUE self) {
|
188
|
+
Hello *hello;
|
189
|
+
const char *message;
|
190
|
+
TypedData_Get_Struct( /* Unwrap the target. */
|
191
|
+
self, Hello, &rb_hello_type, hello);
|
192
|
+
message = hello_message(hello); /* Call. */
|
193
|
+
return rb_str_new_cstr(message); /* C -> Ruby */
|
194
|
+
}
|
195
|
+
|
196
|
+
= Build1\n(('note:ビルド1'))
|
197
|
+
|
198
|
+
# coderay ruby
|
199
|
+
# extconf.rb
|
200
|
+
require "mkmf"
|
201
|
+
# Accept --with-libhello-*.
|
202
|
+
dir_config("libhello")
|
203
|
+
have_header("hello.h")
|
204
|
+
have_library("hello", "hello_new")
|
205
|
+
|
206
|
+
create_makefile("hello")
|
207
|
+
|
208
|
+
= Build2\n(('note:ビルド2'))
|
209
|
+
|
210
|
+
% ruby extconf.rb \
|
211
|
+
--with-libhello-dir=../../libhello
|
212
|
+
% make
|
213
|
+
(hello.so is generated.)
|
214
|
+
|
215
|
+
= Use\n(('note:使う'))
|
216
|
+
|
217
|
+
% LD_LIBRARY_PATH=../../libhello/lib \
|
218
|
+
irb -I .
|
219
|
+
irb(main):001:0> require "hello"
|
220
|
+
=> true
|
221
|
+
irb(main):002:0> hello = Hello.new
|
222
|
+
=> #<Hello:0x00000002ae0e28>
|
223
|
+
irb(main):003:0> hello.message
|
224
|
+
=> "Hello"
|
data/config.yaml
CHANGED
data/fat-gem.rab
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
= Fat gem
|
2
|
+
|
3
|
+
: author
|
4
|
+
Kouhei Sutou
|
5
|
+
: institution
|
6
|
+
ClearCode Inc.
|
7
|
+
: content-source
|
8
|
+
RubyKaigi 2016
|
9
|
+
: date
|
10
|
+
2016-09-08
|
11
|
+
: allotted-time
|
12
|
+
5m
|
13
|
+
: theme
|
14
|
+
.
|
15
|
+
|
16
|
+
= Fat gem?\n(('note:fat gemとは'))
|
17
|
+
|
18
|
+
* Gem includes built binaries\n
|
19
|
+
(('note:ビルド済みバイナリー入りgem'))
|
20
|
+
* (('note:(Mainly)')) Provided for Windows users\n
|
21
|
+
(('note:主にWindowsユーザー向けに提供'))
|
22
|
+
* (('wait'))Windows users don't need C compiler😼\n
|
23
|
+
(('note:WindowsユーザーはCコンパイラーを用意しなくてよい'))
|
24
|
+
|
25
|
+
= Why fat gem is needed?\n(('note:どうしてfat gemが必要なのか'))
|
26
|
+
|
27
|
+
* Most Windows users don't have C compiler\n
|
28
|
+
(('note:多くのWindowsユーザーはコンパイラーを持っていない'))
|
29
|
+
|
30
|
+
= How to create fat gem\n(('note:fat gemの作り方'))
|
31
|
+
|
32
|
+
* Bundle binaries to gem\n
|
33
|
+
(('note:gemにバイナリーをバンドル'))
|
34
|
+
* Use suitable binaries\n
|
35
|
+
(('note:適切なバイナリーを使う'))
|
36
|
+
|
37
|
+
= Path\n(('note:パス'))
|
38
|
+
|
39
|
+
./lib/hello.rb
|
40
|
+
./lib/2.1/hello.so # For Ruby 2.1
|
41
|
+
./lib/2.2/hello.so # For Ruby 2.2
|
42
|
+
./lib/2.3/hello.so # For Ruby 2.3
|
43
|
+
|
44
|
+
= Load\n(('note:読み込み'))
|
45
|
+
|
46
|
+
# coderay ruby
|
47
|
+
# hello.rb
|
48
|
+
begin
|
49
|
+
major, minor, = RUBY_VERSION.split(".")
|
50
|
+
# e.g.: require "2.3/hello.so"
|
51
|
+
require "#{major}.#{minor}/hello.so"
|
52
|
+
rescue LoadError
|
53
|
+
require "hello.so"
|
54
|
+
end
|
55
|
+
|
56
|
+
= Paths for bindings\n(('note:バインディングの時のパス'))
|
57
|
+
|
58
|
+
./lib/hello.rb
|
59
|
+
./lib/2.1/hello.so # For Ruby 2.1
|
60
|
+
./lib/2.2/hello.so # For Ruby 2.2
|
61
|
+
./lib/2.3/hello.so # For Ruby 2.3
|
62
|
+
# ↓Target library's DLL
|
63
|
+
./vendor/local/bin/hello.dll
|
64
|
+
|
65
|
+
= Load for bindings\n(('note:バインディングの時の読み込み'))
|
66
|
+
|
67
|
+
# coderay ruby
|
68
|
+
# hello.rb
|
69
|
+
if /mingw|mswin/ =~ RUBY_PLATFORM
|
70
|
+
ENV["PATH"] += # For finding DLL
|
71
|
+
";#{__dir__}\\..\\vendor\\local\\bin"
|
72
|
+
end
|
73
|
+
begin
|
74
|
+
major, minor, = RUBY_VERSION.split(".")
|
75
|
+
# ...
|
76
|
+
|
77
|
+
= How to create\n(('note:作り方'))
|
78
|
+
|
79
|
+
(1) (('wait'))Build DLLs\n
|
80
|
+
(('note:DLLをビルド'))
|
81
|
+
(2) (('wait'))Bundle DLLs to gem\n
|
82
|
+
(('note:gemにDLLをバンドル'))
|
83
|
+
|
84
|
+
= How to build\n(('note:ビルド方法'))
|
85
|
+
|
86
|
+
* (('wait'))Build on Windows with C compiler\n
|
87
|
+
(('note:Windows上でCコンパイラーでビルド'))
|
88
|
+
* (('wait'))Build on GNU/Linux or OS X with C cross compiler\n
|
89
|
+
(('note:GNU/LinuxまたはOS X上でCクロスコンパイラーでビルド'))
|
90
|
+
* Popular\n
|
91
|
+
(('note:こちらが一般的'))
|
92
|
+
|
93
|
+
= How to cross compile\n(('note:クロスコンパイル方法'))
|
94
|
+
|
95
|
+
(1) Cross compile target Rubyies\n
|
96
|
+
(('note:対象のRubyをクロスコンパイル'))
|
97
|
+
(2) Run (({extconf.rb})) with target Rubies\n
|
98
|
+
(('note:対象のRubyで(({extconf.rb}))を実行'))
|
99
|
+
(3) Cross compile\n
|
100
|
+
(('note:クロスコンパイル'))
|
101
|
+
|
102
|
+
= Fat gem helper gems\n(('note:fat gem作成支援gem'))
|
103
|
+
|
104
|
+
* rake-compiler
|
105
|
+
* Cross compiling and bundling\n
|
106
|
+
(('note:クロスコンパイルとバンドル支援'))
|
107
|
+
* rake-compiler-dock
|
108
|
+
* Prepares build environment\n
|
109
|
+
(('note:ビルド環境用意支援'))
|
110
|
+
|
111
|
+
= Fat gem and bindings\n(('note:fat gemとバインディング'))
|
112
|
+
|
113
|
+
* Bindings need DLL of target library\n
|
114
|
+
(('note:バインディングは対象ライブラリーのDLLも必要'))
|
115
|
+
* Target library should be also cross compiled\n
|
116
|
+
(('note:対象ライブラリーもクロスコンパイルが必要'))
|
117
|
+
|
118
|
+
= How to cross compile1\n(('note:クロスコンパイル方法1'))
|
119
|
+
|
120
|
+
For GNU Autotools:
|
121
|
+
|
122
|
+
% ./configure \
|
123
|
+
--prefix=vendor/local \
|
124
|
+
--host=x86_64-w64-mingw32
|
125
|
+
% make
|
126
|
+
% make install
|
127
|
+
|
128
|
+
= How to cross compile2\n(('note:クロスコンパイル方法2'))
|
129
|
+
|
130
|
+
For CMake:
|
131
|
+
|
132
|
+
% cmake . \
|
133
|
+
-DCMAKE_INSTALL_PREFIX=vendor/local \
|
134
|
+
-DCMAKE_SYSTEM_NAME=Windows \
|
135
|
+
-DCMAKE_SYSTEM_PROCESSOR=x64 \
|
136
|
+
-DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc
|
137
|
+
% make
|
138
|
+
% make install
|
139
|
+
|
140
|
+
= How to bundle\n(('note:バンドル方法'))
|
141
|
+
|
142
|
+
# coderay ruby
|
143
|
+
# #{gem_name}.gemspec
|
144
|
+
Rake::ExtensionTask.new(gem_name, spec) do |ext|
|
145
|
+
# ...
|
146
|
+
ext.cross_compiling do |cross_spec|
|
147
|
+
cross_spec.files +=
|
148
|
+
Dir.glob("vendor/local/**/*")
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
= How to build gem\n(('note:gemのビルド方法'))
|
153
|
+
|
154
|
+
% rake cross native gem
|
155
|
+
|
156
|
+
= How to release gem\n(('note:gemのリリース方法'))
|
157
|
+
|
158
|
+
% gem push pkg/...-x64-mingw32.gem
|
159
|
+
|
160
|
+
= How to install fat gem\n(('note:fat gemのインストール方法'))
|
161
|
+
|
162
|
+
> gem install GEM_NAME
|
163
|
+
|
164
|
+
No special options\n
|
165
|
+
(('note:特別なオプションはない'))
|
@@ -64,7 +64,7 @@ how to create bindings
|
|
64
64
|
* (('wait'))To use Ruby in more cases\n
|
65
65
|
(('note:Rubyをもっといろんな場面で使うため'))
|
66
66
|
* e.g.: (('tag:x-small:Machine leaning, multimedia, full text search, cipher and so on'))\n
|
67
|
-
(('note
|
67
|
+
(('note:例:機械学習、画像・動画・音声処理、全文検索、暗号'))
|
68
68
|
* (('wait'))We can use existing good features in Ruby by bindings\n
|
69
69
|
(('note:バインディングがあると既存のいい機能をRubyで使える'))
|
70
70
|
|
@@ -72,8 +72,8 @@ how to create bindings
|
|
72
72
|
|
73
73
|
* How about becoming a bindings developer?\n
|
74
74
|
(('note:バインディング開発者になりませんか?'))
|
75
|
-
* (('wait'))To expand
|
76
|
-
(('note:Ruby
|
75
|
+
* (('wait'))To expand use cases of Ruby!\n
|
76
|
+
(('note:Rubyを使えるケースを増やすために!'))
|
77
77
|
* (('wait'))Not just an user for\n
|
78
78
|
provided features\n
|
79
79
|
(('note:提供された機能を使う1ユーザーではなく'))
|
@@ -143,7 +143,8 @@ How powerful auto generated bindings\n
|
|
143
143
|
|
144
144
|
= libffi and FFI: 1\n(('note:libffiとFFIとは:1'))
|
145
145
|
|
146
|
-
* libffi: Library to impl. FFI
|
146
|
+
* libffi: Library to impl. FFI\n
|
147
|
+
(('note:FFIを実現するためのライブラリー'))
|
147
148
|
* (('wait'))((*F*))oreign ((*F*))unction ((*I*))nterface
|
148
149
|
* Generally:\n
|
149
150
|
All APIs to impl. bindings\n
|
@@ -205,6 +206,17 @@ How powerful auto generated bindings\n
|
|
205
206
|
void hello_free (Hello *hello);
|
206
207
|
const char *hello_message(Hello *hello);
|
207
208
|
|
209
|
+
= Ext impl. by hand\n(('note:手動での拡張ライブラリーの実装'))
|
210
|
+
|
211
|
+
# img
|
212
|
+
# src = images/bindings-as-extension-library.svg
|
213
|
+
# relative_width = 100
|
214
|
+
|
215
|
+
== Slide properties
|
216
|
+
|
217
|
+
: enable-title-on-image
|
218
|
+
false
|
219
|
+
|
208
220
|
= Ext impl. by hand\n(('note:手動での拡張ライブラリーの実装'))
|
209
221
|
|
210
222
|
(('note:https://github.com/kou/rabbit-slide-kou-rubykaigi-2016/blob/master/c-api/bindings/hello.c'))
|
@@ -273,7 +285,18 @@ How powerful auto generated bindings\n
|
|
273
285
|
|
274
286
|
= Ext impl. by generation\n(('note:自動生成での拡張ライブラリーの実装'))
|
275
287
|
|
276
|
-
|
288
|
+
# img
|
289
|
+
# src = images/bindings-by-swig.svg
|
290
|
+
# relative_height = 100
|
291
|
+
|
292
|
+
== Slide properties
|
293
|
+
|
294
|
+
: enable-title-on-image
|
295
|
+
false
|
296
|
+
|
297
|
+
= Ext impl. by generation\n(('note:自動生成での拡張ライブラリーの実装'))
|
298
|
+
|
299
|
+
* SWIG can generate impl.\n
|
277
300
|
(('note:Simplified Wrapper and Interface Generator'))\n
|
278
301
|
(('note:SWIGで実装を生成できる'))
|
279
302
|
* (('wait'))An user
|
@@ -344,7 +367,8 @@ How powerful auto generated bindings\n
|
|
344
367
|
* (('wait'))By hand: Need more works\n
|
345
368
|
(('note:手動:追加作業あり'))
|
346
369
|
* (('wait'))By generation: No more works\n
|
347
|
-
(('note
|
370
|
+
(('note:(But the bindings may not be easy to use)'))\n
|
371
|
+
(('note:生成:(使いやすくないけど)追加作業なし'))\n
|
348
372
|
This is a large benefit!\n
|
349
373
|
(('note:これは大きな利点!'))
|
350
374
|
|
@@ -360,6 +384,17 @@ How powerful auto generated bindings\n
|
|
360
384
|
(('note:★ Extension library(拡張ライブラリー)'))\n
|
361
385
|
(('note:☆ GObject Introspection: Recommended(オススメ)'))
|
362
386
|
|
387
|
+
= libffi impl. by hand\n(('note:手動でのlibffiベースの実装'))
|
388
|
+
|
389
|
+
# img
|
390
|
+
# src = images/bindings-by-ffi.svg
|
391
|
+
# relative_width = 100
|
392
|
+
|
393
|
+
== Slide properties
|
394
|
+
|
395
|
+
: enable-title-on-image
|
396
|
+
false
|
397
|
+
|
363
398
|
= libffi impl. by hand\n(('note:手動でのlibffiベースの実装'))
|
364
399
|
|
365
400
|
# coderay ruby
|
@@ -403,7 +438,7 @@ How powerful auto generated bindings\n
|
|
403
438
|
class Hello
|
404
439
|
def message
|
405
440
|
LibHello.hello_message(@hello)
|
406
|
-
|
441
|
+
end
|
407
442
|
end
|
408
443
|
|
409
444
|
= Use wrapped impl.\n(('note:ラップした実装を使う'))
|
@@ -416,6 +451,154 @@ How powerful auto generated bindings\n
|
|
416
451
|
=> "Hello"
|
417
452
|
# Object oriented API!
|
418
453
|
|
419
|
-
= libffi impl. by
|
454
|
+
= libffi impl. by gen.\n(('note:自動生成でのlibffiベースの実装'))
|
455
|
+
|
456
|
+
# img
|
457
|
+
# src = images/bindings-by-gobject-introspection.svg
|
458
|
+
# relative_width = 100
|
459
|
+
|
460
|
+
== Slide properties
|
461
|
+
|
462
|
+
: enable-title-on-image
|
463
|
+
false
|
464
|
+
|
465
|
+
= libffi impl. by gen.\n(('note:自動生成でのlibffiベースの実装'))
|
466
|
+
|
467
|
+
# coderay ruby
|
468
|
+
require "gi"
|
469
|
+
Hello = GI.load("Hello")
|
470
|
+
|
471
|
+
= Use libffi impl. by gen.\n(('note:自動生成でのlibffiベースの実装を使う'))
|
472
|
+
|
473
|
+
irb(main):001:0> require "hello"
|
474
|
+
=> true
|
475
|
+
irb(main):002:0> hello = Hello::Hello.new
|
476
|
+
=> #<Hello::Hello:0x2a9de98 ptr=0x2ecd540>
|
477
|
+
irb(main):003:0> hello.message
|
478
|
+
=> "Hello"
|
479
|
+
# Object oriented API!
|
480
|
+
|
481
|
+
= Wrap up1: libffi\n(('note:まとめ1:libffi'))
|
482
|
+
|
483
|
+
* (('wait'))By hand: Need many works\n
|
484
|
+
(('note:手動:たくさん書かないといけない'))
|
485
|
+
* Need more works for easy to use\n
|
486
|
+
(('note:使いやすいAPIにするにはさらに書かないといけない'))
|
487
|
+
* (('wait'))By generation: Less works\n
|
488
|
+
(('note:生成:書くことが少ない'))
|
489
|
+
* No more works for easy to use\n
|
490
|
+
(('note:しかも使いやすいAPIになる'))
|
491
|
+
|
492
|
+
= Wrap up2: libffi\n(('note:まとめ2:libffi'))
|
493
|
+
|
494
|
+
* On maintenance\n
|
495
|
+
e.g.: New functions\n
|
496
|
+
(('note:メンテナンス時:(例:新しい関数が追加された)'))
|
497
|
+
* (('wait'))By hand: Need more works\n
|
498
|
+
(('note:手動:追加作業あり'))
|
499
|
+
* (('wait'))By generation: No more works\n
|
500
|
+
(('note:生成:追加作業なし'))\n
|
501
|
+
This is a large benefit!\n
|
502
|
+
(('note:これは大きな利点!'))
|
503
|
+
|
504
|
+
= SWIG⇔GI: When\n(('note:SWIG⇔GI:生成タイミング'))
|
505
|
+
|
506
|
+
* When are bindings generated?\n
|
507
|
+
(('note:バインディングの生成タイミング'))
|
508
|
+
* (('wait'))On build⇔Runtime\n
|
509
|
+
(('note:ビルド時⇔ランタイム'))
|
510
|
+
* (('wait'))SWIG: Need to build for new ver.\n
|
511
|
+
(('note:新しいバージョンがでたらリビルドが必要'))
|
512
|
+
* (('wait'))GI: No more works for new ver.\n
|
513
|
+
(('note:新しいバージョンがでても追加作業なし'))
|
514
|
+
|
515
|
+
= SWIG⇔GI: Maintenance\n(('note:SWIG⇔GI:メンテナンス'))
|
516
|
+
|
517
|
+
* SWIG: Maintain .i file for each bindings\n
|
518
|
+
(('note:各バインディング用に.iファイルをメンテナンス'))
|
519
|
+
* GI: Maintain annotations for all bindings\n
|
520
|
+
(('note:全バインディング用にアノテーションをメンテナンス'))
|
521
|
+
* (('wait'))We can work together with other language bindings maintainers
|
522
|
+
|
523
|
+
= SWIG: Overview (reprise)\n(('note:SWIG:概要(再掲)'))
|
524
|
+
|
525
|
+
# img
|
526
|
+
# src = images/bindings-by-swig.svg
|
527
|
+
# relative_height = 100
|
528
|
+
|
529
|
+
== Slide properties
|
530
|
+
|
531
|
+
: enable-title-on-image
|
532
|
+
false
|
533
|
+
|
534
|
+
= SWIG: Maintenance\n(('note:SWIG:メンテナンス'))
|
535
|
+
|
536
|
+
# img
|
537
|
+
# src = images/maintain-swig-based-bindings.svg
|
538
|
+
# relative_height = 100
|
539
|
+
|
540
|
+
== Slide properties
|
541
|
+
|
542
|
+
: enable-title-on-image
|
543
|
+
false
|
544
|
+
|
545
|
+
= GI: Overview (reprise)\n(('note:GI:概要(再掲)'))
|
546
|
+
|
547
|
+
# img
|
548
|
+
# src = images/bindings-by-gobject-introspection.svg
|
549
|
+
# relative_width = 100
|
550
|
+
|
551
|
+
== Slide properties
|
552
|
+
|
553
|
+
: enable-title-on-image
|
554
|
+
false
|
555
|
+
|
556
|
+
= GI: Maintenance\n(('note:GI:メンテナンス'))
|
557
|
+
|
558
|
+
# img
|
559
|
+
# src = images/maintain-gobject-introspection-based-bindings.svg
|
560
|
+
# relative_width = 100
|
561
|
+
|
562
|
+
== Slide properties
|
563
|
+
|
564
|
+
: enable-title-on-image
|
565
|
+
false
|
566
|
+
|
567
|
+
= Wrap up1\n(('note:まとめ1'))
|
568
|
+
|
569
|
+
* Bindings: Glue of C and Ruby\n
|
570
|
+
(('note:バインディング:主にCとRubyをつなぐもの'))
|
571
|
+
* (('wait'))You can use features implemented in C from Ruby\n
|
572
|
+
(('note:Cで実装された機能をRubyから使える'))
|
573
|
+
|
574
|
+
= Wrap up2\n(('note:まとめ2'))
|
575
|
+
|
576
|
+
* Bindings expand use cases of Ruby\n
|
577
|
+
(('note:バインディングはRubyを使えるケースを増やす'))
|
578
|
+
* Because they provide existing good features to Ruby\n
|
579
|
+
(('note:バインディングは既存のよい機能をRubyで使えるようにするから'))
|
580
|
+
|
581
|
+
= Wrap up3\n(('note:まとめ3'))
|
582
|
+
|
583
|
+
* Recommend GI based bindings\n
|
584
|
+
(('note:GIベースのバインディングがオススメ'))
|
585
|
+
* For easy to maintain\n
|
586
|
+
(('note:メンテンナンスしやすいから'))
|
587
|
+
* For easy to API\n
|
588
|
+
(('note:使いやすいAPIになるから'))
|
589
|
+
|
590
|
+
(('note:GI: GObject Introspection'))
|
591
|
+
|
592
|
+
= Wrap up4\n(('note:まとめ4'))
|
593
|
+
|
594
|
+
Let's becoming a bindings developer!\n
|
595
|
+
(('note:バインディング開発者になろう!'))
|
596
|
+
|
597
|
+
= Things not talked\n(('note:話さなかったこと'))
|
420
598
|
|
421
|
-
|
599
|
+
* Bindings are difficult to install on Win. Any idea?\n
|
600
|
+
(('note:Windowsでインストールが大変。どうすれば?'))
|
601
|
+
* Performance\n
|
602
|
+
(('note:性能'))
|
603
|
+
* Details of each bindings create method\n
|
604
|
+
(('note:それぞれのバインディング作成方法の詳細'))
|