0
|
1 # GearsOSのinterface
|
|
2
|
|
3 - GearsOSにはモジュール化の仕組みとしてInterface構文が存在します
|
|
4 - JavaやgolangのInterface, Haskellの型クラスに相当する構文です
|
|
5
|
|
6 ## Interfaceで定義するもの
|
2
|
7 - golangのInterfaceでは、関数の集合、及び関数の引数と返り値がinterfaceとして定義されていました
|
|
8 - GearsOSのItnerfaceでも同様に、使用するデータ構造と、関数を記述します
|
|
9 - 使用するデータ(DataGear)はPerlスクリプト側の改良により、`__code`の中に定義しておけば問題ないようになった
|
|
10
|
|
11 ## 書き方(~2019/02/03)
|
|
12
|
|
13 ```
|
|
14 typedef struct InterfaceName<Type, Impl>{
|
|
15 //入出力で使用するデータ構造を記述する
|
|
16 union Data* stack;
|
|
17 union Data* data;
|
|
18 union Data* data1;
|
|
19
|
|
20 // APIとして使用するCodeGearを列挙する
|
|
21 //ここで利用する引数|出力は必ず上で列挙する必要がある
|
|
22 __code whenEmpty(...);
|
|
23 __code clear(Impl* stack,__code next(...));
|
|
24 __code get2(Impl* stack, __code next(Type* data, Type* data1, ...));
|
|
25
|
|
26 //継続先のCodeGear
|
|
27 __code next(...);
|
|
28 } InterfaceName;
|
|
29 ```
|
|
30 - Type
|
|
31 - 自分自身の型
|
|
32 - Impl
|
|
33 - 自分自身の実装の型
|
|
34 - Stackの場合はSingleLinkedStackなど...
|
|
35
|
|
36 ## 書き方(2019/02/03~)
|
|
37
|
|
38 - Perl側を改良したので引数を別で定義する必要がなくなった
|
|
39
|
|
40 ```
|
|
41 typedef struct InterfaceName<Type, Impl>{
|
|
42 // APIとして使用するCodeGearを列挙する
|
|
43 __code whenEmpty(...);
|
|
44 __code clear(Impl* stack,__code next(...));
|
|
45 __code get2(Impl* stack, __code next(Type* data, Type* data1, ...));
|
|
46
|
|
47 //継続先のCodeGear
|
|
48 __code next(...);
|
|
49 } InterfaceName;
|
|
50 ```
|
|
51 ## 仕様QA
|
|
52 `__code`の記述が始まる前に引数を宣言していた場合、宣言された引数のみが使われる。
|
|
53
|
|
54 (`__code`の中の引数はキャプチャされない)
|
|
55
|
|
56 ## Interfaceのファイルを利用するスクリプト
|
|
57 - interfaceのファイルは次のPerlスクリプトで利用され、CbCレベルでは実は参照されません
|
|
58 - `trans_impl.pl`
|
|
59 - cbcファイルの雛形を生成する際に、実装しているファイルから動的に呼び出されます
|
|
60 - ` generate_stub.pl`
|
|
61 - ` generate_context.pl`
|
|
62 - 入出力の引数チェックで行われます
|
|
63 - `generate_context`では、 `context.h`を生成する際に読み込まれます
|
|
64
|
|
65 ## CbCレベルでのInterface
|
|
66 - CbCレベルでは、 stub 及び, `context.h` の `union Data` の定義内で定義されています
|
|
67 - その為 `context.h` を `include`することで、これらの型を利用できます
|
|
68
|
|
69 ## Interfaceの具体例
|
|
70 - [Stack](/Gears/introduction/interface/Stack)
|
|
71
|
|
72 ## Interfaceの実装の具体例
|
|
73 - [SingleLinkedStack](/Gears/introduction/interface/impl/SingleLinkedStack)
|
|
74
|
|
75 ## Q&A
|
|
76
|
|
77 ### Q.「Interefaceに書いたDataGearはどうやって実装側から使うの?」
|
|
78
|
|
79 **A.「引数で与える」**
|
|
80
|
|
81 ### Q.「引数で使ってないけどContextにDataGearを登録したい」
|
|
82
|
|
83 **A.「専用の構文があります」**
|
|
84 - `// data_gear "WantStruct.h"` と書いておくと `generate_context.pl`時に解決される
|
|
85
|
|
86 #### 例
|
|
87
|
|
88 - 例えば `"DataGearExample`をcontextに加えたい場合
|
|
89 - まず最初に対象のヘッダファイルをどこかに作っておく
|
|
90 - `struct DataGearExample`を使いたいCbCファイルに以下の記述を書いておく
|
|
91
|
|
92 ```c
|
|
93 #include "hoge.h"
|
|
94 //data_gear "DataGearExample.h"
|
|
95 ```
|
|
96
|
|
97 - `#interface "hoge.h"`構文もあるが、 `generate_stub`の時点でこの文が消えるので、コメントで追加している
|
|
98
|
|
99 ### Q.Intefaceに値持たせたいんだけど
|
|
100
|
|
101 **A. 値は実装側に持たせるのでInterfaceには書いちゃだめ!!**
|
|
102
|
|
103 - interfaceはあくまでもCodeGearの入出力だけのDataしかない
|
|
104 - 細かなDataはすべて実装に持たせる
|
|
105 - 同じfieldを持つ実装が複数存在する |