rabbit-slide-kou-rubykaigi-2016 2016.9.8.0 → 2016.9.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:それぞれのバインディング作成方法の詳細'))
|