interfaceのマニュアル実装
with Ada.Text_IO; use Ada.Text_IO; with Ada.Unchecked_Conversion; with System.Address_Image; procedure Hello is package P is type Intf is interface; procedure Ex1 (Obj : access Intf) is abstract; type Intf_Access is access all Intf'Class; --pragma Cpp_Class(Intf); --pragma Cpp_Virtual(Ex1); end P; type Manual; type VMT is record Ex1 : access procedure (Obj : access Manual); end record; type VMT_Access is access constant VMT; type Manual is record VMT : VMT_Access; Data : Integer; end record; procedure Ex1 (Obj : access Manual) is begin Put_Line (System.Address_Image (Obj.all'Address)); Put_Line (Obj.Data'Img); end Ex1; type Manual_Access is access all Manual; MyVMT : aliased constant VMT := (Ex1 => Ex1'Access); Obj : aliased Manual := (VMT => MyVMT'Access, Data => 100); function "+" is new Ada.Unchecked_Conversion (Manual_Access, P.Intf_Access); X : P.Intf_Access := +Obj'Access; pragma Assertion_Policy (Ignore); begin Put_Line (System.Address_Image (Obj'Address)); X.Ex1; end Hello;
0257FEB8 0257FEB8 100
これができるということはCOM互換ということで、よしよし。
注意点。
- Cpp_Classとかは別に要らん。
- 引数をaccessではなくinとかにしてるともし値渡しとなったら無駄にハマるので素直にaccessにする。
- 呼びだし時点でAssertion_PolicyをIgnoreにしとかないとTagがチェックされてAssertion_Failureくらう。
gnatpp便利だ。対応して無い構文があるのが惜しい。