Imported Upstream version 1.04
Stefano Zacchiroli
16 years ago
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | |
1 | "http://www.w3.org/TR/REC-html40/loose.dtd"> | |
2 | <HTML> | |
3 | <HEAD><TITLE>Camlidl user's manual | |
4 | Version 1.04</TITLE> | |
5 | ||
6 | <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
7 | <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> | |
8 | </HEAD> | |
9 | <BODY > | |
10 | <!--HEVEA command line is: /usr/local/lib/hevea/hevea -I /home/pauillac/cristal4/xleroy/csldoc/manual -I .. -fix ../main.tex --> | |
11 | <!--HACHA command line is: /usr/local/lib/hevea/hacha main.html --> | |
12 | ||
13 | ||
14 | <H1 ALIGN=center>Camlidl user's manual<BR> | |
15 | Version 1.04</H1> | |
16 | ||
17 | <H3 ALIGN=center>Xavier Leroy<BR> | |
18 | INRIA Rocquencourt</H3> | |
19 | ||
20 | <UL> | |
21 | <LI><A HREF="main001.html"> Overview</A> | |
22 | <UL> | |
23 | <LI><A HREF="main001.html#toc1"> What is IDL?</A> | |
24 | <LI><A HREF="main001.html#toc2"> What is COM?</A> | |
25 | </UL> | |
26 | <LI><A HREF="main002.html"> IDL syntax</A> | |
27 | <UL> | |
28 | <LI><A HREF="main002.html#toc3"> Lexical conventions</A> | |
29 | <LI><A HREF="main002.html#toc4"> Limited expressions</A> | |
30 | <LI><A HREF="main002.html#toc5"> Attributes</A> | |
31 | <LI><A HREF="main002.html#toc6"> Types and declarators</A> | |
32 | <LI><A HREF="main002.html#toc7"> Structures, unions and enumerations</A> | |
33 | <LI><A HREF="main002.html#toc8"> Function declarations</A> | |
34 | <LI><A HREF="main002.html#toc9"> Constant definitions</A> | |
35 | <LI><A HREF="main002.html#toc10"> IDL files</A> | |
36 | </UL> | |
37 | <LI><A HREF="main003.html"> The Caml-IDL mapping</A> | |
38 | <UL> | |
39 | <LI><A HREF="main003.html#toc11"> Base types</A> | |
40 | <LI><A HREF="main003.html#toc12"> Pointers</A> | |
41 | <LI><A HREF="main003.html#toc13"> Arrays</A> | |
42 | <LI><A HREF="main003.html#toc14"> Big arrays</A> | |
43 | <LI><A HREF="main003.html#toc15"> Structs</A> | |
44 | <LI><A HREF="main003.html#toc16"> Unions</A> | |
45 | <LI><A HREF="main003.html#toc17"> Enums</A> | |
46 | <LI><A HREF="main003.html#toc18"> Type definitions</A> | |
47 | <LI><A HREF="main003.html#toc19"> Functions</A> | |
48 | <LI><A HREF="main003.html#toc20"> Interfaces</A> | |
49 | </UL> | |
50 | <LI><A HREF="main004.html"> Using <TT>camlidl</TT></A> | |
51 | <UL> | |
52 | <LI><A HREF="main004.html#toc21"> Overview</A> | |
53 | <LI><A HREF="main004.html#toc22"> Options</A> | |
54 | <LI><A HREF="main004.html#toc23"> The <TT>camlidldll</TT> script</A> | |
55 | </UL> | |
56 | <LI><A HREF="main005.html"> Module <TT>Com</TT>: run-time library for COM components</A> | |
57 | <LI><A HREF="main006.html"> Hints on writing IDL files</A> | |
58 | <UL> | |
59 | <LI><A HREF="main006.html#toc24"> Writing an IDL file for a C library</A> | |
60 | <LI><A HREF="main006.html#toc25"> Sharing IDL files between MIDL and CamlIDL</A> | |
61 | <LI><A HREF="main006.html#toc26"> Dispatch interfaces and type libraries</A> | |
62 | </UL> | |
63 | <LI><A HREF="main007.html"> Release notes</A> | |
64 | </UL> | |
65 | <!--FOOTER--> | |
66 | ||
67 | <HR SIZE=2><BLOCKQUOTE><EM>This document was translated from L<sup>A</sup>T<sub>E</sub>X by | |
68 | <A HREF="http://pauillac.inria.fr/~maranget/hevea/index.html">H<FONT SIZE=2><sup>E</sup></FONT>V<FONT SIZE=2><sup>E</sup></FONT>A and H<FONT SIZE=2><sup>A</sup></FONT>C<FONT SIZE=2><sup>H</sup></FONT>A</A>. | |
69 | </EM></BLOCKQUOTE> | |
70 | </BODY> | |
71 | </HTML> |
0 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | |
1 | "http://www.w3.org/TR/REC-html40/loose.dtd"> | |
2 | <HTML> | |
3 | <HEAD> | |
4 | ||
5 | <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
6 | <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> | |
7 | <TITLE> | |
8 | Overview | |
9 | </TITLE> | |
10 | </HEAD> | |
11 | <BODY > | |
12 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
13 | <A HREF="main002.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
14 | <HR> | |
15 | ||
16 | <H2><A NAME="htoc1">1</A> Overview</H2> | |
17 | Camlidl generates stub code for interfacing Caml with C | |
18 | (as described in chapter ``Interfacing with C'' of the | |
19 | <A HREF="http://caml.inria.fr/ocaml/htmlman/index.html">Objective Caml | |
20 | reference manual</A>) from an IDL description of the C functions to be | |
21 | made available in Caml. | |
22 | Thus, Camlidl automates the most tedious task in interfacing C | |
23 | libraries with Caml programs. It can also be used to interface Caml | |
24 | programs with other languages, as long as those languages have a | |
25 | well-defined C interface.<BR> | |
26 | <BR> | |
27 | In addition, Camlidl provides basic support for COM interfaces and | |
28 | components. It supports both using COM components (usually written in | |
29 | C++ or C) from Caml programs, and packaging Caml objects as | |
30 | COM components that can then be used from C++ or C.<BR> | |
31 | <BR> | |
32 | <A NAME="toc1"></A> | |
33 | <H3><A NAME="htoc2">1.1</A> What is IDL?</H3> | |
34 | IDL stands for Interface Description Language. This is a generic term | |
35 | for a family of small languages that have been developed to provide | |
36 | type specifications for libraries written in C and C++. Those | |
37 | languages resembles C declarations (as found in C header files), with | |
38 | extra annotations to provide more precise types for the arguments and | |
39 | results of the functions.<BR> | |
40 | <BR> | |
41 | The particular IDL used by Camlidl is inspired by Microsoft's IDL, | |
42 | which itself is an extension of the IDL found in DCE (The Open Group's | |
43 | Distributed Common Environment). The initial motivation for those IDLs | |
44 | was to automate the generation of stub code for remote procedure calls | |
45 | and network objects, where the arguments to the function are marshaled | |
46 | at the calling site, then sent across the network or through | |
47 | interprocess communications to a server process, which unmarshals the | |
48 | arguments, compute the function application, marshal the results, | |
49 | sends them back to the calling site, where they are unmarshaled and | |
50 | returned to the caller. IDLs were also found to be very useful for | |
51 | inter-language communications, since the same type information that | |
52 | guides the generation of marshaling stubs can be used to generate | |
53 | stubs to convert between the data representations of several | |
54 | languages.<BR> | |
55 | <BR> | |
56 | <A NAME="toc2"></A> | |
57 | <H3><A NAME="htoc3">1.2</A> What is COM?</H3> | |
58 | COM is Microsoft's Common Object Model. It provides a set of | |
59 | programming conventions as well as system support for packaging | |
60 | C++ objects as executable components that can be used in other | |
61 | programs, either by dynamic linking of the component inside the | |
62 | program, or through interprocess or internetwork communications | |
63 | between the program and a remote server. COM components implement one | |
64 | or several interfaces, (similar to Caml object types or Java | |
65 | interfaces) identified by unique 128-bit interface identifiers (IIDs). | |
66 | COM specifies a standard protocol for reference counting of | |
67 | components, and for asking a component which interfaces it | |
68 | implements.<BR> | |
69 | <BR> | |
70 | While the full range of COM services and third-party components is | |
71 | available only on Microsoft's Windows operating systems, the basic COM | |
72 | conventions can also be used on Unix and other operating systems | |
73 | to exchange objects between Caml and C or C++. Of particular | |
74 | interest is the encapsulation of Caml objects as COM components, which | |
75 | can then be used inside larger C or C++ applications; those | |
76 | applications do not need to know anything about Caml: they just call | |
77 | the component methods as if they were C++ methods or C | |
78 | functions, without knowing that they are actually implemented in Caml.<BR> | |
79 | <BR> | |
80 | For more information about COM, see for instance <EM>Inside COM</EM> | |
81 | by Dale Rogerson (Microsoft Press), or the | |
82 | <A HREF="http://msdn.microsoft.com">Microsoft developer Web site</A>.<BR> | |
83 | <BR> | |
84 | <HR> | |
85 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
86 | <A HREF="main002.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
87 | </BODY> | |
88 | </HTML> |
0 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | |
1 | "http://www.w3.org/TR/REC-html40/loose.dtd"> | |
2 | <HTML> | |
3 | <HEAD> | |
4 | ||
5 | <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
6 | <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> | |
7 | <TITLE> | |
8 | IDL syntax | |
9 | </TITLE> | |
10 | </HEAD> | |
11 | <BODY > | |
12 | <A HREF="main001.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
13 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
14 | <A HREF="main003.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
15 | <HR> | |
16 | ||
17 | <H2><A NAME="htoc4">2</A> IDL syntax</H2> | |
18 | This section describes the syntax of IDL files. IDL syntax is very | |
19 | close to that of C declarations, with extra attributes between | |
20 | brackets adding information to the C types. The following example | |
21 | should give the flavor of the syntax: | |
22 | <PRE> | |
23 | int f([in,string] char * msg); | |
24 | </PRE>This reads: ``<TT>f</TT> is a function taking a character string as input and | |
25 | returning an <TT>int</TT>''.<BR> | |
26 | <BR> | |
27 | <A NAME="toc3"></A> | |
28 | <H3><A NAME="htoc5">2.1</A> Lexical conventions</H3> | |
29 | ||
30 | <H5>Blanks.</H5> Space, newline, horizontal tabulation, carriage | |
31 | return, line feed and form feed are considered as blanks. Blanks are | |
32 | ignored, but they separate adjacent tokens.<BR> | |
33 | <BR> | |
34 | ||
35 | <H5>Comments.</H5> Both C-style comments <TT>/* ... */</TT> and | |
36 | Java-style comments <TT>// ...</TT> are supported. C-style comments are | |
37 | introduced by <TT>/*</TT> and terminated by <TT>*/</TT>. Java-style comments are | |
38 | introduced by <TT>//</TT> and extend to the end of the line. Comments are | |
39 | treated as blank characters. Comments do not occur inside string or | |
40 | character literals. Nested C-style comments are not supported.<BR> | |
41 | <BR> | |
42 | ||
43 | <H5>Identifiers.</H5> Identifiers have the same syntax as in C. | |
44 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
45 | <TR><TD ALIGN=right NOWRAP> | |
46 | <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
47 | <TD ALIGN=right NOWRAP>::=</TD> | |
48 | <TD ALIGN=left NOWRAP> (<TT><FONT COLOR=blue>A</FONT></TT> ... <TT><FONT COLOR=blue>Z</FONT></TT> | <TT><FONT COLOR=blue>a</FONT></TT> ... <TT><FONT COLOR=blue>z</FONT></TT> | <TT><FONT COLOR=blue>_</FONT></TT>) | |
49 | {<TT><FONT COLOR=blue>A</FONT></TT> ... <TT><FONT COLOR=blue>Z</FONT></TT> | <TT><FONT COLOR=blue>a</FONT></TT> ... <TT><FONT COLOR=blue>z</FONT></TT> | <TT><FONT COLOR=blue>0</FONT></TT> ... <TT><FONT COLOR=blue>9</FONT></TT> | <TT><FONT COLOR=blue>_</FONT></TT>}</TD> | |
50 | </TR></TABLE></DIV><BR> | |
51 | ||
52 | <H5>Literals.</H5> Integer literals, character literals and string | |
53 | literals have the same syntax as in C. | |
54 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
55 | <TR><TD ALIGN=right NOWRAP> | |
56 | <TT><I><FONT COLOR=maroon>integer</FONT></I></TT></TD> | |
57 | <TD ALIGN=right NOWRAP>::=</TD> | |
58 | <TD ALIGN=left NOWRAP> [<TT><FONT COLOR=blue>-</FONT></TT>] {<TT><FONT COLOR=blue>0</FONT></TT> ... <TT><FONT COLOR=blue>9</FONT></TT>} | |
59 | [<TT><FONT COLOR=blue>-</FONT></TT>] <TT><FONT COLOR=blue>0x</FONT></TT> {<TT><FONT COLOR=blue>0</FONT></TT> ... <TT><FONT COLOR=blue>9</FONT></TT> | <TT><FONT COLOR=blue>a</FONT></TT> ... <TT><FONT COLOR=blue>f</FONT></TT> | <TT><FONT COLOR=blue>A</FONT></TT> ... <TT><FONT COLOR=blue>F</FONT></TT>} | |
60 | [<TT><FONT COLOR=blue>-</FONT></TT>] <TT><FONT COLOR=blue>0</FONT></TT> {<TT><FONT COLOR=blue>0</FONT></TT> ... <TT><FONT COLOR=blue>7</FONT></TT>}</TD> | |
61 | </TR> | |
62 | <TR><TD ALIGN=right NOWRAP> | |
63 | <TT><I><FONT COLOR=maroon>character</FONT></I></TT></TD> | |
64 | <TD ALIGN=right NOWRAP>::=</TD> | |
65 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>'</FONT></TT> (<TT><I><FONT COLOR=maroon>regular-char</FONT></I></TT> | <TT><I><FONT COLOR=maroon>escape-char</FONT></I></TT>) <TT><FONT COLOR=blue>'</FONT></TT></TD> | |
66 | </TR> | |
67 | <TR><TD ALIGN=right NOWRAP> | |
68 | <TT><I><FONT COLOR=maroon>string</FONT></I></TT></TD> | |
69 | <TD ALIGN=right NOWRAP>::=</TD> | |
70 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>"</FONT></TT> {<TT><I><FONT COLOR=maroon>regular-char</FONT></I></TT> | <TT><I><FONT COLOR=maroon>escape-char</FONT></I></TT>} <TT><FONT COLOR=blue>"</FONT></TT></TD> | |
71 | </TR> | |
72 | <TR><TD ALIGN=right NOWRAP> | |
73 | <TT><I><FONT COLOR=maroon>escape-char</FONT></I></TT></TD> | |
74 | <TD ALIGN=right NOWRAP>::=</TD> | |
75 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>\</FONT></TT> (<TT><FONT COLOR=blue>b</FONT></TT>| <TT><FONT COLOR=blue>n</FONT></TT>| <TT><FONT COLOR=blue>r</FONT></TT>| <TT><FONT COLOR=blue>t</FONT></TT>)</TD> | |
76 | </TR> | |
77 | <TR><TD ALIGN=right NOWRAP> </TD> | |
78 | <TD ALIGN=right NOWRAP>|</TD> | |
79 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>\</FONT></TT> (<TT><FONT COLOR=blue>0</FONT></TT>...<TT><FONT COLOR=blue>7</FONT></TT>) [<TT><FONT COLOR=blue>0</FONT></TT>...<TT><FONT COLOR=blue>7</FONT></TT>] [<TT><FONT COLOR=blue>0</FONT></TT>...<TT><FONT COLOR=blue>7</FONT></TT>]</TD> | |
80 | </TR></TABLE></DIV><BR> | |
81 | ||
82 | <H5>UUID.</H5> Unique identifiers are composed of 16 hexadecimal | |
83 | digits, in groups of 8, 4, 4, 4 and 12, separated by dashes. | |
84 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
85 | <TR><TD ALIGN=right NOWRAP> | |
86 | <TT><I><FONT COLOR=maroon>uuid</FONT></I></TT></TD> | |
87 | <TD ALIGN=right NOWRAP>::=</TD> | |
88 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>hex</FONT></I></TT><SUP><FONT SIZE=2>8</FONT></SUP> <TT><FONT COLOR=blue>-</FONT></TT> <TT><I><FONT COLOR=maroon>hex</FONT></I></TT><SUP><FONT SIZE=2>4</FONT></SUP> <TT><FONT COLOR=blue>-</FONT></TT> <TT><I><FONT COLOR=maroon>hex</FONT></I></TT><SUP><FONT SIZE=2>4</FONT></SUP> <TT><FONT COLOR=blue>-</FONT></TT> <TT><I><FONT COLOR=maroon>hex</FONT></I></TT><SUP><FONT SIZE=2>4</FONT></SUP> <TT><FONT COLOR=blue>-</FONT></TT> <TT><I><FONT COLOR=maroon>hex</FONT></I></TT><SUP><FONT SIZE=2>4</FONT></SUP> <TT><I><FONT COLOR=maroon>hex</FONT></I></TT><SUP><FONT SIZE=2>4</FONT></SUP> <TT><I><FONT COLOR=maroon>hex</FONT></I></TT><SUP><FONT SIZE=2>4</FONT></SUP></TD> | |
89 | </TR> | |
90 | <TR><TD ALIGN=right NOWRAP> | |
91 | <TT><I><FONT COLOR=maroon>hex</FONT></I></TT></TD> | |
92 | <TD ALIGN=right NOWRAP>::=</TD> | |
93 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>0</FONT></TT> ... <TT><FONT COLOR=blue>9</FONT></TT> | <TT><FONT COLOR=blue>a</FONT></TT> ... <TT><FONT COLOR=blue>f</FONT></TT> | <TT><FONT COLOR=blue>A</FONT></TT> ... <TT><FONT COLOR=blue>F</FONT></TT></TD> | |
94 | </TR></TABLE></DIV><BR> | |
95 | <A NAME="toc4"></A> | |
96 | <H3><A NAME="htoc6">2.2</A> Limited expressions</H3> | |
97 | Limited expressions are similar to C expressions, with the omission of | |
98 | assignment operators (<TT>=</TT>, <TT>+=</TT>, etc), and the addition of the | |
99 | unsigned (logical) right shift operator <TT>>>></TT>. Operators have the same | |
100 | precedences and associativities as in C. They are listed below in | |
101 | decreasing priority order. | |
102 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
103 | <TR><TD ALIGN=right NOWRAP> | |
104 | <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
105 | <TD ALIGN=right NOWRAP>::=</TD> | |
106 | <TD ALIGN=left NOWRAP> | |
107 | <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
108 | </TR> | |
109 | <TR><TD ALIGN=right NOWRAP> </TD> | |
110 | <TD ALIGN=right NOWRAP>|</TD> | |
111 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>integer</FONT></I></TT></TD> | |
112 | </TR> | |
113 | <TR><TD ALIGN=right NOWRAP> </TD> | |
114 | <TD ALIGN=right NOWRAP>|</TD> | |
115 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>character</FONT></I></TT></TD> | |
116 | </TR> | |
117 | <TR><TD ALIGN=right NOWRAP> </TD> | |
118 | <TD ALIGN=right NOWRAP>|</TD> | |
119 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>true</FONT></TT></TD> | |
120 | </TR> | |
121 | <TR><TD ALIGN=right NOWRAP> </TD> | |
122 | <TD ALIGN=right NOWRAP>|</TD> | |
123 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>false</FONT></TT></TD> | |
124 | </TR> | |
125 | <TR><TD ALIGN=right NOWRAP> </TD> | |
126 | <TD ALIGN=right NOWRAP>|</TD> | |
127 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>string</FONT></I></TT></TD> | |
128 | </TR> | |
129 | <TR><TD ALIGN=right NOWRAP> </TD> | |
130 | <TD ALIGN=right NOWRAP>|</TD> | |
131 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>sizeof</FONT></I></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>type-expr</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT></TD> | |
132 | </TR> | |
133 | <TR><TD ALIGN=right NOWRAP> </TD> | |
134 | <TD ALIGN=right NOWRAP>|</TD> | |
135 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT></TD> | |
136 | </TR> | |
137 | <TR><TD ALIGN=right NOWRAP> </TD> | |
138 | <TD ALIGN=right NOWRAP>|</TD> | |
139 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> (<TT><FONT COLOR=blue>.</FONT></TT> | <TT><FONT COLOR=blue>-></FONT></TT>) <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
140 | </TR> | |
141 | <TR><TD ALIGN=right NOWRAP> </TD> | |
142 | <TD ALIGN=right NOWRAP>|</TD> | |
143 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>type-expr</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
144 | </TR> | |
145 | <TR><TD ALIGN=right NOWRAP> </TD> | |
146 | <TD ALIGN=right NOWRAP>|</TD> | |
147 | <TD ALIGN=left NOWRAP> (<TT><FONT COLOR=blue>&</FONT></TT>| <TT><FONT COLOR=blue>*</FONT></TT>| <TT><FONT COLOR=blue>!</FONT></TT>| <TT><FONT COLOR=blue>~</FONT></TT>| <TT><FONT COLOR=blue>-</FONT></TT>| <TT><FONT COLOR=blue>+</FONT></TT>) <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
148 | </TR> | |
149 | <TR><TD ALIGN=right NOWRAP> </TD> | |
150 | <TD ALIGN=right NOWRAP>|</TD> | |
151 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> (<TT><FONT COLOR=blue>*</FONT></TT>| <TT><FONT COLOR=blue>/</FONT></TT>| <TT><FONT COLOR=blue>%</FONT></TT>) <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
152 | </TR> | |
153 | <TR><TD ALIGN=right NOWRAP> </TD> | |
154 | <TD ALIGN=right NOWRAP>|</TD> | |
155 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> (<TT><FONT COLOR=blue>+</FONT></TT>| <TT><FONT COLOR=blue>-</FONT></TT>) <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
156 | </TR> | |
157 | <TR><TD ALIGN=right NOWRAP> </TD> | |
158 | <TD ALIGN=right NOWRAP>|</TD> | |
159 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> (<TT><FONT COLOR=blue><<</FONT></TT>| <TT><FONT COLOR=blue>>></FONT></TT></TD> | |
160 | </TR> | |
161 | <TR><TD ALIGN=right NOWRAP> </TD> | |
162 | <TD ALIGN=right NOWRAP>|</TD> | |
163 | <TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>>>></FONT></TT>) <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
164 | </TR> | |
165 | <TR><TD ALIGN=right NOWRAP> </TD> | |
166 | <TD ALIGN=right NOWRAP>|</TD> | |
167 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> (<TT><FONT COLOR=blue>==</FONT></TT>| <TT><FONT COLOR=blue>!=</FONT></TT>| <TT><FONT COLOR=blue>>=</FONT></TT>| <TT><FONT COLOR=blue><=</FONT></TT>| <TT><FONT COLOR=blue>></FONT></TT>| <TT><FONT COLOR=blue><</FONT></TT>)</TD> | |
168 | </TR> | |
169 | <TR><TD ALIGN=right NOWRAP> </TD> | |
170 | <TD ALIGN=right NOWRAP>|</TD> | |
171 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> (<TT><FONT COLOR=blue>&</FONT></TT>| <TT><FONT COLOR=blue>^</FONT></TT>| <TT><FONT COLOR=blue>|</FONT></TT>) <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
172 | </TR> | |
173 | <TR><TD ALIGN=right NOWRAP> </TD> | |
174 | <TD ALIGN=right NOWRAP>|</TD> | |
175 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> (<TT><FONT COLOR=blue>&&</FONT></TT>| <TT><FONT COLOR=blue>||</FONT></TT>) <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
176 | </TR> | |
177 | <TR><TD ALIGN=right NOWRAP> </TD> | |
178 | <TD ALIGN=right NOWRAP>|</TD> | |
179 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> <TT><FONT COLOR=blue>?</FONT></TT> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT> <TT><FONT COLOR=blue>:</FONT></TT> <TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT></TD> | |
180 | </TR></TABLE></DIV> | |
181 | Constant limited expressions, written <TT><I><FONT COLOR=maroon>const-lexpr</FONT></I></TT> below, can only | |
182 | reference identifiers that are bound by the IDL <TT>const</TT> declaration.<BR> | |
183 | <BR> | |
184 | <A NAME="toc5"></A> | |
185 | <H3><A NAME="htoc7">2.3</A> Attributes</H3><BR> | |
186 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
187 | <TR><TD ALIGN=right NOWRAP> | |
188 | <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT></TD> | |
189 | <TD ALIGN=right NOWRAP>::=</TD> | |
190 | <TD ALIGN=left NOWRAP> | |
191 | <TT><FONT COLOR=blue>[</FONT></TT> <TT><I><FONT COLOR=maroon>attribute</FONT></I></TT> { <TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>attribute</FONT></I></TT> } <TT><FONT COLOR=blue>]</FONT></TT></TD> | |
192 | </TR> | |
193 | <TR><TD ALIGN=right NOWRAP> | |
194 | <TT><I><FONT COLOR=maroon>attribute</FONT></I></TT></TD> | |
195 | <TD ALIGN=right NOWRAP>::=</TD> | |
196 | <TD ALIGN=left NOWRAP> | |
197 | <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
198 | </TR> | |
199 | <TR><TD ALIGN=right NOWRAP> </TD> | |
200 | <TD ALIGN=right NOWRAP>|</TD> | |
201 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>(</FONT></TT> [<TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT>] { <TT><FONT COLOR=blue>,</FONT></TT> [<TT><I><FONT COLOR=maroon>lexpr</FONT></I></TT>] } <TT><FONT COLOR=blue>)</FONT></TT></TD> | |
202 | </TR> | |
203 | <TR><TD ALIGN=right NOWRAP> </TD> | |
204 | <TD ALIGN=right NOWRAP>|</TD> | |
205 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>uuid</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT></TD> | |
206 | </TR> | |
207 | <TR><TD ALIGN=right NOWRAP> </TD> | |
208 | <TD ALIGN=right NOWRAP>|</TD> | |
209 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>attribute</FONT></I></TT> <TT><FONT COLOR=blue>*</FONT></TT></TD> | |
210 | </TR> | |
211 | <TR><TD ALIGN=right NOWRAP> </TD> | |
212 | <TD ALIGN=right NOWRAP>|</TD> | |
213 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>*</FONT></TT> <TT><I><FONT COLOR=maroon>attribute</FONT></I></TT></TD> | |
214 | </TR></TABLE></DIV> | |
215 | Attribute lists are written in brackets <TT>[...]</TT>, and are always | |
216 | optional. Each attribute is identified by a name, and may carry | |
217 | optional arguments. Starred attributes apply to the element type of a | |
218 | pointer or array type, rather than to the pointer or array type itself. | |
219 | The following table summarizes the recognized attributes and their | |
220 | arguments.<BR> | |
221 | <DIV ALIGN=center><TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1 WIDTH="80%"> | |
222 | <TR><TD ALIGN=center NOWRAP><B>Attribute</B></TD> | |
223 | <TD ALIGN=center NOWRAP><B>Context where it can appear</B></TD> | |
224 | </TR> | |
225 | <TR><TD ALIGN=left NOWRAP> | |
226 | <TT><FONT COLOR=blue>abstract</FONT></TT> </TD> | |
227 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
228 | </TR> | |
229 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>bigarray</FONT></TT> </TD> | |
230 | <TD ALIGN=left NOWRAP>array type</TD> | |
231 | </TR> | |
232 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>camlint</FONT></TT> </TD> | |
233 | <TD ALIGN=left NOWRAP><TT>int</TT> or <TT>long</TT> integer type</TD> | |
234 | </TR> | |
235 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>compare</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>fun-name</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
236 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
237 | </TR> | |
238 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>c2ml</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>fun-name</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
239 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
240 | </TR> | |
241 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>errorcheck</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>fun-name</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
242 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
243 | </TR> | |
244 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>errorcode</FONT></TT> </TD> | |
245 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
246 | </TR> | |
247 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>finalize</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>fun-name</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
248 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
249 | </TR> | |
250 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>fortran</FONT></TT> </TD> | |
251 | <TD ALIGN=left NOWRAP>array type with <TT>bigarray</TT> attribute</TD> | |
252 | </TR> | |
253 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>hash</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>fun-name</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
254 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
255 | </TR> | |
256 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>ignore</FONT></TT> </TD> | |
257 | <TD ALIGN=left NOWRAP>any pointer type</TD> | |
258 | </TR> | |
259 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>in</FONT></TT> </TD> | |
260 | <TD ALIGN=left NOWRAP>function parameter</TD> | |
261 | </TR> | |
262 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>int_default</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT> <TT><FONT COLOR=blue>camlint</FONT></TT>| <TT><FONT COLOR=blue>nativeint</FONT></TT>| <TT><FONT COLOR=blue>int32</FONT></TT>| <TT><FONT COLOR=blue>int64</FONT></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
263 | <TD ALIGN=left NOWRAP>interface</TD> | |
264 | </TR> | |
265 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>int32</FONT></TT> </TD> | |
266 | <TD ALIGN=left NOWRAP><TT>int</TT> or <TT>long</TT> integer type</TD> | |
267 | </TR> | |
268 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>int64</FONT></TT> </TD> | |
269 | <TD ALIGN=left NOWRAP><TT>int</TT> or <TT>long</TT> integer type</TD> | |
270 | </TR> | |
271 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>length_is</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>le</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB><TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>le</FONT></I></TT><SUB><FONT SIZE=2>2</FONT></SUB><TT><FONT COLOR=blue>,</FONT></TT>...<TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
272 | <TD ALIGN=left NOWRAP>array type</TD> | |
273 | </TR> | |
274 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>long_default</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT> <TT><FONT COLOR=blue>camlint</FONT></TT>| <TT><FONT COLOR=blue>nativeint</FONT></TT>| <TT><FONT COLOR=blue>int32</FONT></TT>| <TT><FONT COLOR=blue>int64</FONT></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
275 | <TD ALIGN=left NOWRAP>interface</TD> | |
276 | </TR> | |
277 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>managed</FONT></TT> </TD> | |
278 | <TD ALIGN=left NOWRAP>array type with <TT>bigarray</TT> attribute</TD> | |
279 | </TR> | |
280 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>ml2c</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>fun-name</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
281 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
282 | </TR> | |
283 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>mlname(</FONT></TT> <TT><I><FONT COLOR=maroon>label-name</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
284 | <TD ALIGN=left NOWRAP><TT>struct</TT> field</TD> | |
285 | </TR> | |
286 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>mltype("</FONT></TT> <TT><I><FONT COLOR=maroon>caml-type-expr</FONT></I></TT> <TT><FONT COLOR=blue>")</FONT></TT> </TD> | |
287 | <TD ALIGN=left NOWRAP><TT>typedef</TT></TD> | |
288 | </TR> | |
289 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>nativeint</FONT></TT> </TD> | |
290 | <TD ALIGN=left NOWRAP><TT>int</TT> or <TT>long</TT> integer type</TD> | |
291 | </TR> | |
292 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>null_terminated</FONT></TT> </TD> | |
293 | <TD ALIGN=left NOWRAP>array of pointers</TD> | |
294 | </TR> | |
295 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>object</FONT></TT></TD> | |
296 | <TD ALIGN=left NOWRAP>interface</TD> | |
297 | </TR> | |
298 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>out</FONT></TT> </TD> | |
299 | <TD ALIGN=left NOWRAP>function parameter</TD> | |
300 | </TR> | |
301 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>pointer_default</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT> <TT><FONT COLOR=blue>ref</FONT></TT>| <TT><FONT COLOR=blue>unique</FONT></TT>| <TT><FONT COLOR=blue>ptr</FONT></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
302 | <TD ALIGN=left NOWRAP>interface</TD> | |
303 | </TR> | |
304 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>propget</FONT></TT></TD> | |
305 | <TD ALIGN=left NOWRAP>function declaration</TD> | |
306 | </TR> | |
307 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>propput</FONT></TT></TD> | |
308 | <TD ALIGN=left NOWRAP>function declaration</TD> | |
309 | </TR> | |
310 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>propputref</FONT></TT></TD> | |
311 | <TD ALIGN=left NOWRAP>function declaration</TD> | |
312 | </TR> | |
313 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>ptr</FONT></TT> </TD> | |
314 | <TD ALIGN=left NOWRAP>any pointer type</TD> | |
315 | </TR> | |
316 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>ref</FONT></TT> </TD> | |
317 | <TD ALIGN=left NOWRAP>any pointer type</TD> | |
318 | </TR> | |
319 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>set</FONT></TT> </TD> | |
320 | <TD ALIGN=left NOWRAP>enum type</TD> | |
321 | </TR> | |
322 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>size_is</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>le</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB><TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>le</FONT></I></TT><SUB><FONT SIZE=2>2</FONT></SUB><TT><FONT COLOR=blue>,</FONT></TT>...<TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
323 | <TD ALIGN=left NOWRAP>array type</TD> | |
324 | </TR> | |
325 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>string</FONT></TT> </TD> | |
326 | <TD ALIGN=left NOWRAP>character array or pointer</TD> | |
327 | </TR> | |
328 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>switch_is</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>le</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
329 | <TD ALIGN=left NOWRAP>union type or pointer to union</TD> | |
330 | </TR> | |
331 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>switch_type</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>ty</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
332 | <TD ALIGN=left NOWRAP>union or pointer to union</TD> | |
333 | </TR> | |
334 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>unique</FONT></TT> </TD> | |
335 | <TD ALIGN=left NOWRAP>any pointer, array, or bigarray type</TD> | |
336 | </TR> | |
337 | <TR><TD ALIGN=left NOWRAP><TT><FONT COLOR=blue>uuid</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>uuid</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> </TD> | |
338 | <TD ALIGN=left NOWRAP>interface</TD> | |
339 | </TR></TABLE></DIV><BR> | |
340 | <A NAME="toc6"></A> | |
341 | <H3><A NAME="htoc8">2.4</A> Types and declarators</H3> | |
342 | The declaration of an identifier along with its type is as in C: | |
343 | a type specification comes first, followed by the identifier possibly | |
344 | decorated with <TT>*</TT> and <TT>[...]</TT> to denote pointers and array types. | |
345 | For instance, <TT>int x</TT> declares an identifier <TT>x</TT> of type <TT>int</TT>, | |
346 | while <TT>int (*x)[]</TT> declares an identifier <TT>x</TT> that is a pointer to an | |
347 | array of integers. | |
348 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
349 | <TR><TD ALIGN=right NOWRAP> | |
350 | <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT></TD> | |
351 | <TD ALIGN=right NOWRAP>::=</TD> | |
352 | <TD ALIGN=left NOWRAP> | |
353 | [<TT><FONT COLOR=blue>unsigned</FONT></TT>| <TT><FONT COLOR=blue>signed</FONT></TT>] | |
354 | (<TT><FONT COLOR=blue>int</FONT></TT>| <TT><FONT COLOR=blue>short</FONT></TT>| <TT><FONT COLOR=blue>long</FONT></TT>| <TT><FONT COLOR=blue>char</FONT></TT>| <TT><FONT COLOR=blue>hyper</FONT></TT>| <TT><FONT COLOR=blue>long</FONT></TT> <TT><FONT COLOR=blue>long</FONT></TT>| <TT><FONT COLOR=blue>__int64</FONT></TT>)</TD> | |
355 | </TR> | |
356 | <TR><TD ALIGN=right NOWRAP> </TD> | |
357 | <TD ALIGN=right NOWRAP>|</TD> | |
358 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>byte</FONT></TT></TD> | |
359 | </TR> | |
360 | <TR><TD ALIGN=right NOWRAP> </TD> | |
361 | <TD ALIGN=right NOWRAP>|</TD> | |
362 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>float</FONT></TT></TD> | |
363 | </TR> | |
364 | <TR><TD ALIGN=right NOWRAP> </TD> | |
365 | <TD ALIGN=right NOWRAP>|</TD> | |
366 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>double</FONT></TT></TD> | |
367 | </TR> | |
368 | <TR><TD ALIGN=right NOWRAP> </TD> | |
369 | <TD ALIGN=right NOWRAP>|</TD> | |
370 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>boolean</FONT></TT></TD> | |
371 | </TR> | |
372 | <TR><TD ALIGN=right NOWRAP> </TD> | |
373 | <TD ALIGN=right NOWRAP>|</TD> | |
374 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>void</FONT></TT></TD> | |
375 | </TR> | |
376 | <TR><TD ALIGN=right NOWRAP> </TD> | |
377 | <TD ALIGN=right NOWRAP>|</TD> | |
378 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
379 | </TR> | |
380 | <TR><TD ALIGN=right NOWRAP> </TD> | |
381 | <TD ALIGN=right NOWRAP>|</TD> | |
382 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>wchar_t</FONT></TT></TD> | |
383 | </TR> | |
384 | <TR><TD ALIGN=right NOWRAP> </TD> | |
385 | <TD ALIGN=right NOWRAP>|</TD> | |
386 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>handle_t</FONT></TT></TD> | |
387 | </TR> | |
388 | <TR><TD ALIGN=right NOWRAP> </TD> | |
389 | <TD ALIGN=right NOWRAP>|</TD> | |
390 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>struct</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
391 | </TR> | |
392 | <TR><TD ALIGN=right NOWRAP> </TD> | |
393 | <TD ALIGN=right NOWRAP>|</TD> | |
394 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>union</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
395 | </TR> | |
396 | <TR><TD ALIGN=right NOWRAP> </TD> | |
397 | <TD ALIGN=right NOWRAP>|</TD> | |
398 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>enum</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
399 | </TR> | |
400 | <TR><TD ALIGN=right NOWRAP> </TD> | |
401 | <TD ALIGN=right NOWRAP>|</TD> | |
402 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>struct-decl</FONT></I></TT></TD> | |
403 | </TR> | |
404 | <TR><TD ALIGN=right NOWRAP> </TD> | |
405 | <TD ALIGN=right NOWRAP>|</TD> | |
406 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>union-decl</FONT></I></TT></TD> | |
407 | </TR> | |
408 | <TR><TD ALIGN=right NOWRAP> </TD> | |
409 | <TD ALIGN=right NOWRAP>|</TD> | |
410 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>enum-decl</FONT></I></TT></TD> | |
411 | </TR> | |
412 | <TR><TD ALIGN=right NOWRAP> | |
413 | <TT><I><FONT COLOR=maroon>declarator</FONT></I></TT></TD> | |
414 | <TD ALIGN=right NOWRAP>::=</TD> | |
415 | <TD ALIGN=left NOWRAP> | |
416 | {<TT><FONT COLOR=blue>*</FONT></TT>} <TT><I><FONT COLOR=maroon>direct-declarator</FONT></I></TT></TD> | |
417 | </TR> | |
418 | <TR><TD ALIGN=right NOWRAP> | |
419 | <TT><I><FONT COLOR=maroon>direct-declarator</FONT></I></TT></TD> | |
420 | <TD ALIGN=right NOWRAP>::=</TD> | |
421 | <TD ALIGN=left NOWRAP> | |
422 | <TT><I><FONT COLOR=maroon>ident</FONT></I></TT></TD> | |
423 | </TR> | |
424 | <TR><TD ALIGN=right NOWRAP> </TD> | |
425 | <TD ALIGN=right NOWRAP>|</TD> | |
426 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>declarator</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT></TD> | |
427 | </TR> | |
428 | <TR><TD ALIGN=right NOWRAP> </TD> | |
429 | <TD ALIGN=right NOWRAP>|</TD> | |
430 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>direct-declarator</FONT></I></TT> <TT><FONT COLOR=blue>[</FONT></TT> [<TT><I><FONT COLOR=maroon>const-lexpr</FONT></I></TT>] <TT><FONT COLOR=blue>]</FONT></TT></TD> | |
431 | </TR></TABLE></DIV><BR> | |
432 | <A NAME="toc7"></A> | |
433 | <H3><A NAME="htoc9">2.5</A> Structures, unions and enumerations</H3><BR> | |
434 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
435 | <TR><TD ALIGN=right NOWRAP> | |
436 | <TT><I><FONT COLOR=maroon>struct-decl</FONT></I></TT></TD> | |
437 | <TD ALIGN=right NOWRAP>::=</TD> | |
438 | <TD ALIGN=left NOWRAP> | |
439 | <TT><FONT COLOR=blue>struct</FONT></TT> [<TT><I><FONT COLOR=maroon>ident</FONT></I></TT>] <TT><FONT COLOR=blue>{</FONT></TT> {<TT><I><FONT COLOR=maroon>field-decl</FONT></I></TT>} <TT><FONT COLOR=blue>}</FONT></TT></TD> | |
440 | </TR> | |
441 | <TR><TD ALIGN=right NOWRAP> | |
442 | <TT><I><FONT COLOR=maroon>field-decl</FONT></I></TT></TD> | |
443 | <TD ALIGN=right NOWRAP>::=</TD> | |
444 | <TD ALIGN=left NOWRAP> | |
445 | <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT> <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT> <TT><I><FONT COLOR=maroon>declarator</FONT></I></TT> { <TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>declarator</FONT></I></TT> } <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
446 | </TR> | |
447 | <TR><TD ALIGN=right NOWRAP> | |
448 | <TT><I><FONT COLOR=maroon>union-decl</FONT></I></TT></TD> | |
449 | <TD ALIGN=right NOWRAP>::=</TD> | |
450 | <TD ALIGN=left NOWRAP> | |
451 | <TT><FONT COLOR=blue>union</FONT></TT> [<TT><I><FONT COLOR=maroon>ident</FONT></I></TT>] <TT><FONT COLOR=blue>{</FONT></TT> {<TT><I><FONT COLOR=maroon>union-case</FONT></I></TT>} <TT><FONT COLOR=blue>}</FONT></TT></TD> | |
452 | </TR> | |
453 | <TR><TD ALIGN=right NOWRAP> </TD> | |
454 | <TD ALIGN=right NOWRAP>|</TD> | |
455 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>union</FONT></TT> [<TT><I><FONT COLOR=maroon>ident</FONT></I></TT>] <TT><FONT COLOR=blue>switch</FONT></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> <TT><FONT COLOR=blue>{</FONT></TT> {<TT><I><FONT COLOR=maroon>union-case</FONT></I></TT>} <TT><FONT COLOR=blue>}</FONT></TT></TD> | |
456 | </TR> | |
457 | <TR><TD ALIGN=right NOWRAP> | |
458 | <TT><I><FONT COLOR=maroon>union-case</FONT></I></TT></TD> | |
459 | <TD ALIGN=right NOWRAP>::=</TD> | |
460 | <TD ALIGN=left NOWRAP> | |
461 | {<TT><FONT COLOR=blue>case</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>:</FONT></TT>}<SUP><FONT SIZE=2>+</FONT></SUP> [<TT><I><FONT COLOR=maroon>field-decl</FONT></I></TT>] <TT><FONT COLOR=blue>;</FONT></TT> | |
462 | <TT><FONT COLOR=blue>default</FONT></TT> <TT><FONT COLOR=blue>:</FONT></TT> [<TT><I><FONT COLOR=maroon>field-decl</FONT></I></TT>] <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
463 | </TR> | |
464 | <TR><TD ALIGN=right NOWRAP> | |
465 | <TT><I><FONT COLOR=maroon>enum-decl</FONT></I></TT></TD> | |
466 | <TD ALIGN=right NOWRAP>::=</TD> | |
467 | <TD ALIGN=left NOWRAP> | |
468 | <TT><FONT COLOR=blue>enum</FONT></TT> [<TT><I><FONT COLOR=maroon>ident</FONT></I></TT>] <TT><FONT COLOR=blue>{</FONT></TT> <TT><I><FONT COLOR=maroon>enum-case</FONT></I></TT> {<TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>enum-case</FONT></I></TT>} [<TT><FONT COLOR=blue>,</FONT></TT>] <TT><FONT COLOR=blue>}</FONT></TT></TD> | |
469 | </TR> | |
470 | <TR><TD ALIGN=right NOWRAP> | |
471 | <TT><I><FONT COLOR=maroon>enum-case</FONT></I></TT></TD> | |
472 | <TD ALIGN=right NOWRAP>::=</TD> | |
473 | <TD ALIGN=left NOWRAP> | |
474 | <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> [<TT><FONT COLOR=blue>=</FONT></TT> <TT><I><FONT COLOR=maroon>const-lexpr</FONT></I></TT>]</TD> | |
475 | </TR></TABLE></DIV><BR> | |
476 | IDL <TT>struct</TT> declarations are like those of C, with the addition of | |
477 | optional attributes on each field. <TT>union</TT> declarations are also as | |
478 | in C, except that each case of an union must be labeled by one or | |
479 | several <TT><FONT COLOR=blue>case</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>:</FONT></TT>. The first form of union declaration | |
480 | assumes that the discriminant of the union is provided separately | |
481 | via a <TT>switch_is</TT> annotation on the union type, while the second form | |
482 | encapsulates the discriminant along with the union itself | |
483 | (like in Pascal's <TT>record case of</TT> construct).<BR> | |
484 | <BR> | |
485 | <A NAME="toc8"></A> | |
486 | <H3><A NAME="htoc10">2.6</A> Function declarations</H3><BR> | |
487 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
488 | <TR><TD ALIGN=right NOWRAP> | |
489 | <TT><I><FONT COLOR=maroon>function-decl</FONT></I></TT></TD> | |
490 | <TD ALIGN=right NOWRAP>::=</TD> | |
491 | <TD ALIGN=left NOWRAP> | |
492 | <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT> <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT> {<TT><FONT COLOR=blue>*</FONT></TT>} <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>params</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> {<TT><FONT COLOR=blue>quote</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT><TT><I><FONT COLOR=maroon>ident</FONT></I></TT><TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>string</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT>}</TD> | |
493 | </TR> | |
494 | <TR><TD ALIGN=right NOWRAP> | |
495 | <TT><I><FONT COLOR=maroon>params</FONT></I></TT></TD> | |
496 | <TD ALIGN=right NOWRAP>::=</TD> | |
497 | <TD ALIGN=left NOWRAP> | |
498 | <FONT FACE=symbol>e</FONT></TD> | |
499 | </TR> | |
500 | <TR><TD ALIGN=right NOWRAP> </TD> | |
501 | <TD ALIGN=right NOWRAP>|</TD> | |
502 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>void</FONT></TT></TD> | |
503 | </TR> | |
504 | <TR><TD ALIGN=right NOWRAP> </TD> | |
505 | <TD ALIGN=right NOWRAP>|</TD> | |
506 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>param</FONT></I></TT> { <TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>param</FONT></I></TT> }</TD> | |
507 | </TR> | |
508 | <TR><TD ALIGN=right NOWRAP> | |
509 | <TT><I><FONT COLOR=maroon>param</FONT></I></TT></TD> | |
510 | <TD ALIGN=right NOWRAP>::=</TD> | |
511 | <TD ALIGN=left NOWRAP> | |
512 | <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT> <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT> <TT><I><FONT COLOR=maroon>declarator</FONT></I></TT></TD> | |
513 | </TR></TABLE></DIV> | |
514 | Function declarations are like in ANSI C, with the addition of | |
515 | attributes on each parameter and on the function itself. | |
516 | Parameters must be named. The optional <TT><I><FONT COLOR=maroon>quote</FONT></I></TT> statements following the | |
517 | declaration are user-provided calling sequences and deallocation | |
518 | sequences that replaces the default sequences in the | |
519 | <TT>camlidl</TT>-generated stub code for the function.<BR> | |
520 | <BR> | |
521 | <A NAME="toc9"></A> | |
522 | <H3><A NAME="htoc11">2.7</A> Constant definitions</H3><BR> | |
523 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
524 | <TR><TD ALIGN=right NOWRAP> | |
525 | <TT><I><FONT COLOR=maroon>constant-decl</FONT></I></TT></TD> | |
526 | <TD ALIGN=right NOWRAP>::=</TD> | |
527 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>const</FONT></TT> <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT> <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT> {<TT><FONT COLOR=blue>*</FONT></TT>} <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>=</FONT></TT> <TT><I><FONT COLOR=maroon>const-lexpr</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
528 | </TR></TABLE></DIV> | |
529 | A constant declaration associates a name to a limited expression. | |
530 | The limited expression can refer to constant names declared earlier, | |
531 | but cannot refer to other kinds of identifiers. The optional | |
532 | attributes influence the interpretation of the type specification, | |
533 | e.g. <TT>const int x = 3</TT> defines <TT>x</TT> with Caml type <TT>int</TT>, but | |
534 | <TT>const [int64] long x = 5</TT> defines <TT>x</TT> with Caml type <TT>int64</TT>.<BR> | |
535 | <BR> | |
536 | <A NAME="toc10"></A> | |
537 | <H3><A NAME="htoc12">2.8</A> IDL files</H3><BR> | |
538 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
539 | <TR><TD ALIGN=right NOWRAP> | |
540 | <TT><I><FONT COLOR=maroon>file</FONT></I></TT></TD> | |
541 | <TD ALIGN=right NOWRAP>::=</TD> | |
542 | <TD ALIGN=left NOWRAP> {<TT><I><FONT COLOR=maroon>decl</FONT></I></TT>}</TD> | |
543 | </TR> | |
544 | <TR><TD ALIGN=right NOWRAP> | |
545 | <TT><I><FONT COLOR=maroon>decl</FONT></I></TT></TD> | |
546 | <TD ALIGN=right NOWRAP>::=</TD> | |
547 | <TD ALIGN=left NOWRAP> | |
548 | <TT><I><FONT COLOR=maroon>function-decl</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
549 | </TR> | |
550 | <TR><TD ALIGN=right NOWRAP> </TD> | |
551 | <TD ALIGN=right NOWRAP>|</TD> | |
552 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>constant-decl</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
553 | </TR> | |
554 | <TR><TD ALIGN=right NOWRAP> </TD> | |
555 | <TD ALIGN=right NOWRAP>|</TD> | |
556 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>struct-decl</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
557 | </TR> | |
558 | <TR><TD ALIGN=right NOWRAP> </TD> | |
559 | <TD ALIGN=right NOWRAP>|</TD> | |
560 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>union-decl</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
561 | </TR> | |
562 | <TR><TD ALIGN=right NOWRAP> </TD> | |
563 | <TD ALIGN=right NOWRAP>|</TD> | |
564 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>enum-decl</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
565 | </TR> | |
566 | <TR><TD ALIGN=right NOWRAP> </TD> | |
567 | <TD ALIGN=right NOWRAP>|</TD> | |
568 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>typedef</FONT></TT> <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT> <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT> <TT><I><FONT COLOR=maroon>declarator</FONT></I></TT> { <TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>declarator</FONT></I></TT> } <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
569 | </TR> | |
570 | <TR><TD ALIGN=right NOWRAP> </TD> | |
571 | <TD ALIGN=right NOWRAP>|</TD> | |
572 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT> <TT><FONT COLOR=blue>interface</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> [ <TT><FONT COLOR=blue>:</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> ] <TT><FONT COLOR=blue>{</FONT></TT> {<TT><I><FONT COLOR=maroon>decl</FONT></I></TT>} <TT><FONT COLOR=blue>}</FONT></TT></TD> | |
573 | </TR> | |
574 | <TR><TD ALIGN=right NOWRAP> </TD> | |
575 | <TD ALIGN=right NOWRAP>|</TD> | |
576 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>struct</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
577 | </TR> | |
578 | <TR><TD ALIGN=right NOWRAP> </TD> | |
579 | <TD ALIGN=right NOWRAP>|</TD> | |
580 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>union</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
581 | </TR> | |
582 | <TR><TD ALIGN=right NOWRAP> </TD> | |
583 | <TD ALIGN=right NOWRAP>|</TD> | |
584 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>union</FONT></TT> <TT><FONT COLOR=blue>switch</FONT></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
585 | </TR> | |
586 | <TR><TD ALIGN=right NOWRAP> </TD> | |
587 | <TD ALIGN=right NOWRAP>|</TD> | |
588 | <TD ALIGN=left NOWRAP> <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT> <TT><FONT COLOR=blue>interface</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
589 | </TR> | |
590 | <TR><TD ALIGN=right NOWRAP> </TD> | |
591 | <TD ALIGN=right NOWRAP>|</TD> | |
592 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>import</FONT></TT> <TT><I><FONT COLOR=maroon>string</FONT></I></TT> <TT><FONT COLOR=blue>;</FONT></TT></TD> | |
593 | </TR> | |
594 | <TR><TD ALIGN=right NOWRAP> </TD> | |
595 | <TD ALIGN=right NOWRAP>|</TD> | |
596 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>quote</FONT></TT> <TT><FONT COLOR=blue>(</FONT></TT> [<TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>,</FONT></TT>] <TT><I><FONT COLOR=maroon>string</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT></TD> | |
597 | </TR> | |
598 | <TR><TD ALIGN=right NOWRAP> </TD> | |
599 | <TD ALIGN=right NOWRAP>|</TD> | |
600 | <TD ALIGN=left NOWRAP> <TT><FONT COLOR=blue>cpp_quote</FONT></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>string</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT></TD> | |
601 | </TR></TABLE></DIV> | |
602 | An IDL file is a sequence of IDL declarations. Declarations include | |
603 | function declarations, constant declarations, type declarations | |
604 | (structs, unions, enums, as well as a C-style <TT>typedef</TT> declaration to | |
605 | name a type expression), and interfaces.<BR> | |
606 | <BR> | |
607 | An interface declaration gives a name and attributes to a collection | |
608 | of declarations. For interfaces with the <TT>object</TT> attribute, | |
609 | an optional super-interface can be provided, as in | |
610 | <TT><FONT COLOR=blue>interface</FONT></TT> <TT><I><FONT COLOR=maroon>intf</FONT></I></TT> <TT><FONT COLOR=blue>:</FONT></TT> <TT><I><FONT COLOR=maroon>super-intf</FONT></I></TT>. The name of the interface can be | |
611 | used as a type name in the remainder of the file.<BR> | |
612 | <BR> | |
613 | Forward declarations of structs, unions and interfaces are supported | |
614 | in the usual C manner, by just giving the name of the struct, union or | |
615 | interface, but not its actual contents.<BR> | |
616 | <BR> | |
617 | The <TT>import</TT> statement reads another IDL file and makes available its | |
618 | type and constant declarations in the remainder of the file. | |
619 | No code is generated for the functions and interfaces declared in the | |
620 | imported file. The same file can be imported several times, but is | |
621 | read in only the first time.<BR> | |
622 | <BR> | |
623 | The <TT><FONT COLOR=blue>quote</FONT></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>str</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> diversion copies the string <TT><I><FONT COLOR=maroon>str</FONT></I></TT> | |
624 | verbatim to one of the files generated by the <TT>camlidl</TT> compiler. | |
625 | The <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> determines the file where <TT><I><FONT COLOR=maroon>str</FONT></I></TT> is copied: | |
626 | it can be <TT>ml</TT> for the Caml implementation file (<TT>.ml</TT>), | |
627 | <TT>mli</TT> for the Caml interface file (<TT>.mli</TT>), | |
628 | <TT>mlmli</TT> for both Caml files, | |
629 | <TT>h</TT> for the C header file (<TT>.h</TT>), | |
630 | and <TT>c</TT> for the C source file containing the generated stub code (<TT>.c</TT> | |
631 | file). For backward compatibility, <TT><FONT COLOR=blue>cpp_quote</FONT></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>str</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> is | |
632 | recognized as synonymous for <TT><FONT COLOR=blue>quote</FONT></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><FONT COLOR=blue>h</FONT></TT> <TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>str</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT>.<BR> | |
633 | <BR> | |
634 | <HR> | |
635 | <A HREF="main001.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
636 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
637 | <A HREF="main003.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
638 | </BODY> | |
639 | </HTML> |
0 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | |
1 | "http://www.w3.org/TR/REC-html40/loose.dtd"> | |
2 | <HTML> | |
3 | <HEAD> | |
4 | ||
5 | <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
6 | <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> | |
7 | <TITLE> | |
8 | The Caml-IDL mapping | |
9 | </TITLE> | |
10 | </HEAD> | |
11 | <BODY > | |
12 | <A HREF="main002.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
13 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
14 | <A HREF="main004.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
15 | <HR> | |
16 | ||
17 | <H2><A NAME="htoc13">3</A> The Caml-IDL mapping</H2> | |
18 | This section describes how IDL types, function declarations, and | |
19 | interfaces are mapped to Caml types, functions and classes.<BR> | |
20 | <BR> | |
21 | <A NAME="toc11"></A> | |
22 | <H3><A NAME="htoc14">3.1</A> Base types</H3><BR> | |
23 | <DIV ALIGN=center><TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1 WIDTH="80%"> | |
24 | <TR><TD ALIGN=center NOWRAP><B>IDL type <I>ty</I></B></TD> | |
25 | <TD ALIGN=center NOWRAP><B>Caml type [[<I>ty</I></B><B>]]</B></TD> | |
26 | </TR> | |
27 | <TR><TD ALIGN=left NOWRAP> | |
28 | <TT>byte</TT>, <TT>short</TT></TD> | |
29 | <TD ALIGN=left NOWRAP><TT>int</TT></TD> | |
30 | </TR> | |
31 | <TR><TD ALIGN=left NOWRAP><TT>int</TT>, <TT>long</TT> with <TT>[camlint]</TT> attribute</TD> | |
32 | <TD ALIGN=left NOWRAP><TT>int</TT></TD> | |
33 | </TR> | |
34 | <TR><TD ALIGN=left NOWRAP><TT>int</TT>, <TT>long</TT> with <TT>[nativeint]</TT> attribute</TD> | |
35 | <TD ALIGN=left NOWRAP><TT>nativeint</TT></TD> | |
36 | </TR> | |
37 | <TR><TD ALIGN=left NOWRAP><TT>int</TT>, <TT>long</TT> with <TT>[int32]</TT> attribute</TD> | |
38 | <TD ALIGN=left NOWRAP><TT>int32</TT></TD> | |
39 | </TR> | |
40 | <TR><TD ALIGN=left NOWRAP><TT>int</TT>, <TT>long</TT> with <TT>[int64]</TT> attribute</TD> | |
41 | <TD ALIGN=left NOWRAP><TT>int64</TT></TD> | |
42 | </TR> | |
43 | <TR><TD ALIGN=left NOWRAP><TT>hyper</TT>, <TT>long long</TT>, <TT>__int64</TT></TD> | |
44 | <TD ALIGN=left NOWRAP><TT>int64</TT></TD> | |
45 | </TR> | |
46 | <TR><TD ALIGN=left NOWRAP><TT>char</TT></TD> | |
47 | <TD ALIGN=left NOWRAP><TT>char</TT></TD> | |
48 | </TR> | |
49 | <TR><TD ALIGN=left NOWRAP><TT>float</TT>, <TT>double</TT></TD> | |
50 | <TD ALIGN=left NOWRAP><TT>float</TT></TD> | |
51 | </TR> | |
52 | <TR><TD ALIGN=left NOWRAP><TT>boolean</TT></TD> | |
53 | <TD ALIGN=left NOWRAP><TT>bool</TT></TD> | |
54 | </TR></TABLE></DIV><BR> | |
55 | ||
56 | (For integer types, <TT>signed</TT> and <TT>unsigned</TT> variants of the same IDL | |
57 | integer type translate to the same Caml type.)<BR> | |
58 | <BR> | |
59 | Depending on the attributes, the <TT>int</TT> and <TT>long</TT> integer types are | |
60 | converted to one of the Caml integer types <TT>int</TT>, <TT>nativeint</TT>, | |
61 | <TT>int32</TT>, or <TT>int64</TT>. Values of Caml type <TT>int32</TT> are exactly 32-bit wide | |
62 | and values of type <TT>int64</TT> are exactly 64-bit wide on all platforms. | |
63 | Values of type <TT>nativeint</TT> have the natural word size of the platform, | |
64 | and are large enough to accommodate any C <TT>int</TT> or <TT>long int</TT> without | |
65 | loss of precision. Values of Caml type <TT>int</TT> have the natural word | |
66 | size of the platform minus one bit of tag, hence the conversion from IDL | |
67 | types <TT>int</TT> and <TT>long</TT> loses the most significant bit on 32-bit | |
68 | platforms. On 64-bit platforms, the conversion from <TT>int</TT> is exact, | |
69 | but the conversion from <TT>long</TT> loses the most significant bit.<BR> | |
70 | <BR> | |
71 | If no explicit integer attribute is given for an <TT>int</TT> or <TT>long</TT> type, | |
72 | the <TT>int_default</TT> or <TT>long_default</TT> attribute of the enclosing | |
73 | interface, if any, determines the kind of the integer. | |
74 | If no <TT>int_default</TT> or <TT>long_default</TT> attribute is in scope, the kind | |
75 | <TT>camlint</TT> is assumed, which maps IDL <TT>int</TT> and <TT>long</TT> types to the | |
76 | Caml <TT>int</TT> type.<BR> | |
77 | <BR> | |
78 | <A NAME="toc12"></A> | |
79 | <H3><A NAME="htoc15">3.2</A> Pointers</H3> | |
80 | The mapping of IDL pointer types depends on their kinds. Writing | |
81 | [[<I>ty</I>]] for the Caml type corresponding to the IDL type | |
82 | <I>ty</I>, we have: | |
83 | <PRE> | |
84 | [ref] <I>ty</I> * <FONT FACE=symbol>Þ</FONT> [[<I>ty</I>]] | |
85 | [unique] <I>ty</I> * <FONT FACE=symbol>Þ</FONT> [[<I>ty</I>]] option | |
86 | [ptr] <I>ty</I> * <FONT FACE=symbol>Þ</FONT> [[<I>ty</I>]] Com.opaque | |
87 | </PRE> | |
88 | In other terms, IDL pointers of kind <TT>ref</TT> are ignored during the mapping: | |
89 | <TT>[ref] </TT><I>ty</I><TT> *</TT> is mapped to the same Caml type as <I>ty</I>. | |
90 | A pointer <I>p</I> to a C value <I>c</I><TT> = *</TT><I>p</I> is translated to | |
91 | the Caml value corresponding to <I>c</I>.<BR> | |
92 | <BR> | |
93 | IDL pointers of kind <TT>unique</TT> are mapped to an <TT>option</TT> type. The | |
94 | option value is <TT>None</TT> for a null pointer, and <TT>Some(</TT><I>v</I><TT>)</TT> | |
95 | for a non-null pointer to a C value <I>c</I> that translates to the ML | |
96 | value <I>v</I>.<BR> | |
97 | <BR> | |
98 | IDL pointers of kind <TT>ptr</TT> are mapped to a <TT>Com.opaque</TT> type. | |
99 | This is an abstract type that encapsulates the C pointer without | |
100 | attempting to convert it to an ML data structure.<BR> | |
101 | <BR> | |
102 | IDL pointers of kind <TT>ignore</TT> denote struct fields and function | |
103 | parameters that need not be exposed in the Caml code. Those pointers | |
104 | are simply set to null when converting from Caml to C, and ignored | |
105 | when converting from C to Caml. They cannot occur elsewhere.<BR> | |
106 | <BR> | |
107 | If no explicit pointer kind is given, the <TT>pointer_default</TT> attribute | |
108 | of the enclosing interface, if any, determines the kind of the pointer. | |
109 | If no <TT>pointer_default</TT> attribute is in scope, the kind <TT>unique</TT> is | |
110 | assumed.<BR> | |
111 | <BR> | |
112 | <A NAME="toc13"></A> | |
113 | <H3><A NAME="htoc16">3.3</A> Arrays</H3> | |
114 | IDL arrays of characters that carry the <TT>[string]</TT> attribute are mapped | |
115 | to the Caml <TT>string</TT> type: | |
116 | <BR> | |
117 | <DIV ALIGN=center><TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1 WIDTH="80%"> | |
118 | <TR><TD ALIGN=center NOWRAP><B>IDL type <I>ty</I></B></TD> | |
119 | <TD ALIGN=center NOWRAP><B>Caml type [[<I>ty</I></B><B>]]</B></TD> | |
120 | </TR> | |
121 | <TR><TD ALIGN=left NOWRAP> | |
122 | <TT>[string] char []</TT></TD> | |
123 | <TD ALIGN=left NOWRAP><TT>string</TT></TD> | |
124 | </TR> | |
125 | <TR><TD ALIGN=left NOWRAP><TT>[string] unsigned char []</TT></TD> | |
126 | <TD ALIGN=left NOWRAP><TT>string</TT></TD> | |
127 | </TR> | |
128 | <TR><TD ALIGN=left NOWRAP><TT>[string] signed char []</TT></TD> | |
129 | <TD ALIGN=left NOWRAP><TT>string</TT></TD> | |
130 | </TR> | |
131 | <TR><TD ALIGN=left NOWRAP><TT>[string] byte []</TT></TD> | |
132 | <TD ALIGN=left NOWRAP><TT>string</TT></TD> | |
133 | </TR></TABLE></DIV><BR> | |
134 | ||
135 | Caml string values are translated to standard null-terminated C strings. | |
136 | Be careful about embedded null characters in the Caml string, which | |
137 | will be recognized as end of string by C functions.<BR> | |
138 | <BR> | |
139 | IDL arrays carrying the <TT>[bigarray]</TT> attribute are translated to Caml | |
140 | ``big arrays'', as described in the next section.<BR> | |
141 | <BR> | |
142 | All other IDL arrays are translated to ML arrays: | |
143 | <PRE> | |
144 | <I>ty</I> [] <FONT FACE=symbol>Þ</FONT> [[<I>ty</I>]] array | |
145 | </PRE> | |
146 | For instance, <TT>double []</TT> becomes <TT>float array</TT>. | |
147 | Consequently, multi-dimensional arrays are translated to Caml arrays | |
148 | of arrays. For instance, <TT>int [][]</TT> becomes <TT>int array array</TT>.<BR> | |
149 | <BR> | |
150 | If the <TT>unique</TT> attribute is given, the IDL array is translated to an | |
151 | ML option type: | |
152 | <PRE> | |
153 | [string,unique] char [] <FONT FACE=symbol>Þ</FONT> string option | |
154 | [unique] <I>ty</I> [] <FONT FACE=symbol>Þ</FONT> [[<I>ty</I>]] array option | |
155 | </PRE> | |
156 | As in the case of pointers of kind <TT>unique</TT>, the option value is | |
157 | <TT>None</TT> for a null C pointer, and <TT>Some(</TT><I>v</I><TT>)</TT> for a non-null | |
158 | C pointer to a C array that translates to the ML string or array <I>v</I>.<BR> | |
159 | <BR> | |
160 | Conversion between a C array and an ML array proceed element by | |
161 | element. For the conversion from C to ML, the number of elements of | |
162 | the ML array is determined as follows (in the order presented): | |
163 | <UL><LI> | |
164 | By the <TT>length_is</TT> attribute, if present. | |
165 | <LI>By the <TT>size_is</TT> attribute, if present. | |
166 | <LI>By the bound written in the array type, if any. | |
167 | <LI>By searching the first null element of the C array, if the | |
168 | <TT>null_terminated</TT> attribute is present. | |
169 | </UL> | |
170 | For instance, C values of IDL type <TT>[length_is(n)] double[]</TT> are | |
171 | mapped to Caml <TT>float array</TT> of <TT>n</TT> elements. C values of IDL type | |
172 | <TT>double[10]</TT> are mapped to Caml <TT>float array</TT> of 10 elements.<BR> | |
173 | <BR> | |
174 | The <TT>length_is</TT> and <TT>size_is</TT> attributes take as argument one or | |
175 | several limited expressions. Each expression applies to one dimension | |
176 | of the array. For instance, <TT>[size_is(*dimx, *dimy)] double d[][]</TT> | |
177 | specifies a matrix of <TT>double</TT> whose first dimension has size | |
178 | <TT>*dimx</TT> and the second has size <TT>*dimy</TT>.<BR> | |
179 | <BR> | |
180 | <A NAME="toc14"></A> | |
181 | <H3><A NAME="htoc17">3.4</A> Big arrays</H3> | |
182 | IDL arrays of integers or floats that carry the <TT>[bigarray]</TT> attribute | |
183 | are mapped to one of the Caml <TT>Bigarray</TT> types: <TT>Array1.t</TT> for | |
184 | one-dimensional arrays, <TT>Array2.t</TT> for 2-dimensional arrays, | |
185 | <TT>Array3.t</TT> for 3-dimensional arrays, and <TT>Genarray.t</TT> for arrays of 4 | |
186 | dimensions or more.<BR> | |
187 | <BR> | |
188 | If the <TT>[fortran]</TT> attribute is given, the big array is accessed | |
189 | from Caml using the Fortran conventions (array indices start at 1; | |
190 | column-major memory layout). By default, the big array is accessed | |
191 | from Caml using the C conventions (array indices start at 0; row-major | |
192 | memory layout).<BR> | |
193 | <BR> | |
194 | If the <TT>[managed]</TT> attribute is given on a big array type that is | |
195 | result type or out parameter type of a function, Caml assumes that the | |
196 | corresponding C array was allocated using <TT>malloc()</TT>, and is not | |
197 | referenced anywhere else; then, the Caml garbage collector will free | |
198 | the C array when the corresponding Caml big array becomes unreachable. | |
199 | By default, Caml assumes that result or out C arrays are statically or | |
200 | permanently allocated, and keeps a pointer to them during conversion | |
201 | to Caml big arrays, and does not free them when the Caml bigarrays | |
202 | become unreachable.<BR> | |
203 | <BR> | |
204 | Finally, the <TT>[unique]</TT> attribute applies to bigarrays as to arrays, | |
205 | that is, it maps a null C pointer to <TT>None</TT>, and a non-null C pointer | |
206 | <I>p</I> to <TT>Some(</TT><I>v</I><TT>)</TT> where <I>v</I> is the ML bigarray | |
207 | resulting from the translation of <I>p</I>.<BR> | |
208 | <BR> | |
209 | <A NAME="toc15"></A> | |
210 | <H3><A NAME="htoc18">3.5</A> Structs</H3> | |
211 | IDL structs are mapped to Caml record types. The names and types of | |
212 | the IDL struct fields determine the names and types of the Caml record | |
213 | type: | |
214 | <PRE> | |
215 | struct <I>s</I> { ... ; <I>ty</I><SUB><FONT SIZE=2><I>i</I></FONT></SUB> <I>id</I><SUB><FONT SIZE=2><I>i</I></FONT></SUB> ; ... } becomes type <I>s</I> = { ... ; <I>id</I><SUB><FONT SIZE=2><I>i</I></FONT></SUB> : [[<I>ty</I><SUB><FONT SIZE=2><I>i</I></FONT></SUB>]] ; ... } | |
216 | </PRE> | |
217 | Example: <TT>struct s { int n; double d[4]; }</TT> becomes | |
218 | <TT>type s = {n: int; d: float array}</TT>.<BR> | |
219 | <BR> | |
220 | Exceptions to this rule are as follows: | |
221 | <UL><LI> | |
222 | Fields of the IDL struct that are pointers with the <TT>[ignore]</TT> | |
223 | attribute do not appear in the Caml record type. | |
224 | Example: <TT>struct s { double x,y; [ignore] void * data; }</TT> | |
225 | becomes <TT>type struct_s = {x : float; y: float}</TT>. | |
226 | Those ignored pointer fields are set to <TT>NULL</TT> when converting from a | |
227 | Caml record to a C struct.<BR> | |
228 | <BR> | |
229 | <LI>Integer fields of the IDL struct that appear in a <TT>length_is</TT>, | |
230 | <TT>size_is</TT> or <TT>switch_is</TT> attribute of another field also do not appear | |
231 | in the Caml record type. (We call those fields <EM>dependent</EM> fields.) | |
232 | Example: <TT>struct s { int idx; int len; [size_is(len)] double d[]; }</TT> | |
233 | is translated to the Caml record type | |
234 | <TT>type struct_s = {idx: int; d: float array}</TT>. | |
235 | The value of <TT>len</TT> is recovered from the size of the Caml array <TT>d</TT>, | |
236 | and thus doesn't need to be represented explicitly in the Caml record.<BR> | |
237 | <BR> | |
238 | <LI>If, after elimination of ignored pointer fields and dependent | |
239 | fields as described above, the IDL struct has only one field | |
240 | <I>ty</I> <I>id</I>, we avoid creating a one-field Caml record type | |
241 | and translate the IDL struct type directly to the Caml type | |
242 | [[<I>ty</I>]]. | |
243 | Example: <TT>struct s { int len; [size_is(len)] double d[]; }</TT> | |
244 | is translated to the Caml type abbreviation <TT>type struct_s = double array</TT>.<BR> | |
245 | <BR> | |
246 | <LI>The names of labels in the Caml record type can be changed by | |
247 | using the <TT><FONT COLOR=blue>mlname</FONT></TT> attribute on struct field declarations. For instance, | |
248 | <PRE> | |
249 | struct s { int n; [mlname(p)] int q; } | |
250 | becomes type s = { n : int; p : int } | |
251 | </PRE><BR> | |
252 | <BR> | |
253 | <LI>The Caml type system makes it difficult to use two record types | |
254 | defined in the same module and having some label names in common. | |
255 | Thus, if CamlIDL encounters two or more structs having | |
256 | identically-named fields, it prefixes the Caml label names by the names | |
257 | of the structs in order to distinguish them. For instance: | |
258 | <PRE> | |
259 | struct s1 { int x; int y; } | |
260 | struct s2 { double x; double t; } | |
261 | struct s3 { int z; } | |
262 | becomes type s1 = { s1_x: int; s1_y: int } | |
263 | and s2 = { s2_x: float; s2_t: float } | |
264 | and s3 = { z: int } | |
265 | </PRE> | |
266 | The labels for <TT>s1</TT> and <TT>s2</TT> have been prefixed by <TT>s1_</TT> and | |
267 | <TT>s2_</TT> respectively, to avoid ambiguity on the <TT>x</TT> label. However, the | |
268 | label <TT>z</TT> for <TT>s3</TT> is not prefixed, since it is not used elsewhere.<BR> | |
269 | <BR> | |
270 | The prefix added in front of multiply-defined labels is taken from the | |
271 | struct name, if any, and otherwise from the name of the nearest | |
272 | enclosing struct, union or typedef. For instance: | |
273 | <PRE> | |
274 | typedef struct { int x; } t; | |
275 | struct s4 { struct { int x; } z; }; | |
276 | becomes type t = { t_x: int } | |
277 | and s4 = { z: struct_1 } | |
278 | and struct_1 = { s4_x: int } | |
279 | </PRE> | |
280 | The ``minimal prefixing'' strategy described above is the default | |
281 | behavior of <TT>camlidl</TT>. If the <TT>-prefix-all-labels</TT> option is given, | |
282 | all record labels are prefixed, whether they occur several times or | |
283 | not. If the <TT>-keep-labels</TT> option is given, no automatic prefixing | |
284 | takes place; the naming of record labels is left entirely under the | |
285 | user's control, via <TT><FONT COLOR=blue>mlname</FONT></TT> annotations.</UL> | |
286 | <A NAME="toc16"></A> | |
287 | <H3><A NAME="htoc19">3.6</A> Unions</H3> | |
288 | IDL discriminated unions are translated to Caml sum types. Each case | |
289 | of the union corresponds to a constructor of the sum type. The | |
290 | constructor is constant if the union case has no associated field, | |
291 | otherwise has one argument corresponding to the union case field. If | |
292 | the union has a <TT>default</TT> case, an extra constructor | |
293 | <TT>Default_</TT><I>unionname</I> is added to the Caml sum type, carrying an | |
294 | <TT>int</TT> argument (the value of the discriminating field), | |
295 | and possibly another argument corresponding to the default field. | |
296 | Examples: | |
297 | <PRE> | |
298 | union u1 { case A: int x; case B: case C: double d; case D: ; } | |
299 | becomes type u1 = A of int | B of float | C of float | D | |
300 | union u2 { case A: int x; case B: double d; default: ; } | |
301 | becomes type u2 = A of int | B of float | Default_u of int | |
302 | union u3 { case A: int x; default: double d; } | |
303 | becomes type u3 = A of int | Default_v of int * double | |
304 | </PRE> | |
305 | All IDL unions must be discriminated, either via the special syntax | |
306 | <TT>union </TT><I>name</I><TT> switch(int </TT><I>discr</I><TT>)</TT>..., or via the | |
307 | attribute <TT>switch_is(</TT><I>discr</I><TT>)</TT>, where <I>discr</I> is a C l-value | |
308 | built from other parameters of the current function, or other fields | |
309 | of the current <TT>struct</TT>. Both the discriminant and the | |
310 | case labels must be of an integer type. Unless a <TT>default</TT> case is | |
311 | given, the value of the discriminant must be one of the cases of the | |
312 | union.<BR> | |
313 | <BR> | |
314 | <A NAME="toc17"></A> | |
315 | <H3><A NAME="htoc20">3.7</A> Enums</H3> | |
316 | IDL enums are translated to Caml enumerated types (sum types with only | |
317 | constant constructors). The names of the constructors are determined | |
318 | by the names of the enum labels. The values attached to the enum | |
319 | labels are ignored. | |
320 | Example: | |
321 | <TT>enum e { A, B = 2, C = 4 }</TT> becomes <TT>type enum_e = A | B | C</TT>.<BR> | |
322 | <BR> | |
323 | The <TT><FONT COLOR=blue>set</FONT></TT> attribute can be applied to a named enum to denote a | |
324 | bitfield obtained by logical ``or'' of zero, one or several labels of | |
325 | the enum. The corresponding ML value is a list of zero, one or | |
326 | several constructors of the Caml enumerated type. Consider for | |
327 | instance: | |
328 | <PRE> | |
329 | enum e { A = 1, B = 2, C = 4 }; | |
330 | typedef [set] enum e eset; | |
331 | </PRE>The Caml type <TT>eset</TT> is equal to <TT>enum_e list</TT>. | |
332 | The C integer 6 (= <TT>B | C</TT>) is translated to the ML list <TT>[B; C]</TT>. | |
333 | The ML list <TT>[A; C]</TT> is translated to the C integer <TT>A | C</TT>, that is <TT>5</TT>.<BR> | |
334 | <BR> | |
335 | <A NAME="toc18"></A> | |
336 | <H3><A NAME="htoc21">3.8</A> Type definitions</H3> | |
337 | An IDL <TT>typedef</TT> statement is normally translated | |
338 | to a Caml type abbreviation. For instance, | |
339 | <TT>typedef [string] char * str</TT> becomes <TT>type str = string</TT>.<BR> | |
340 | <BR> | |
341 | If the <TT><FONT COLOR=blue>abstract</FONT></TT> attribute is given, a Caml abstract type is | |
342 | generated instead of a type abbreviation, thus hinding from Caml the | |
343 | representation of the type in question. For instance, | |
344 | <TT>typedef [abstract] void * handle</TT> becomes <TT>type handle</TT>. | |
345 | In this case, the IDL type in the <TT>typedef</TT> is ignored.<BR> | |
346 | <BR> | |
347 | If the <TT><FONT COLOR=blue>mltype</FONT></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><FONT COLOR=blue>"</FONT></TT> <TT><I><FONT COLOR=maroon>caml-type-expr</FONT></I></TT> <TT><FONT COLOR=blue>"</FONT></TT> <TT><FONT COLOR=blue>)</FONT></TT> attribute is given, | |
348 | the Caml type is made equal to <TT><I><FONT COLOR=maroon>caml-type-expr</FONT></I></TT>. This is often used | |
349 | in conjunction with the <TT><FONT COLOR=blue>ml2c</FONT></TT> and <TT><FONT COLOR=blue>c2ml</FONT></TT> attributes to implement | |
350 | custom translation of data structures between C and ML. For instance, | |
351 | <TT>typedef [mltype("int list")] struct mylist_struct * mylist</TT> | |
352 | becomes <TT>type mylist = int list</TT>.<BR> | |
353 | <BR> | |
354 | If the <TT><FONT COLOR=blue>c2ml(</FONT></TT><TT><I><FONT COLOR=maroon>funct-name</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> <TT><I><FONT COLOR=maroon>and</FONT></I></TT> <TT>ml2c(</TT>funct-name<TT>)</TT> attributes are | |
355 | given, the user-provided C functions given as attributes will be | |
356 | called to perform Caml to C and C to Caml conversions for values of | |
357 | the typedef-ed type, instead of using the <TT>camlidl</TT>-generated | |
358 | conversion functions. This allows user-controlled translation of data | |
359 | structures. The prototypes of the conversion functions must be | |
360 | <PRE> | |
361 | value c2ml(<I>ty</I> * input); | |
362 | void ml2c(value input, <I>ty</I> * output); | |
363 | </PRE> | |
364 | where <I>ty</I> is the name of the type defined by <TT>typedef</TT>. In other | |
365 | terms, the <TT>c2ml</TT> function is passed a reference to a <I>ty</I> and | |
366 | returns the corresponding Caml value, while the <TT>ml2c</TT> function is | |
367 | passed a Caml value as first argument and stores the corresponding C | |
368 | value in the <I>ty</I> reference passed as second argument.<BR> | |
369 | <BR> | |
370 | If the <TT><FONT COLOR=blue>finalize(</FONT></TT><TT><I><FONT COLOR=maroon>final-fn</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> attribute is given in combination with the | |
371 | <TT><FONT COLOR=blue>abstract</FONT></TT> attribute, the function <TT><I><FONT COLOR=maroon>final-fn</FONT></I></TT> is called when | |
372 | the Caml block representing a value of this typedef becomes | |
373 | unreachable from Caml and is reclaimed by the Caml garbage collector. | |
374 | Similarly, <TT><FONT COLOR=blue>compare(</FONT></TT><TT><I><FONT COLOR=maroon>compare-fn</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> and <TT><FONT COLOR=blue>hash(</FONT></TT><TT><I><FONT COLOR=maroon>hash-fn</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> attach a | |
375 | comparison function and a hashing function (respectively) to Caml | |
376 | values for this typedef. The comparison function is called when two | |
377 | Caml values of this typedef are compared using the generic comparisons | |
378 | <TT>compare</TT>, <TT>=</TT>, <TT><</TT>, etc. The hashing function is called when | |
379 | <TT>Hashtbl.hash</TT> is applied to a Caml value of this typedef. | |
380 | The prototype of the finalization, comparison and hashing functions are: | |
381 | <PRE> | |
382 | value <I>final-fn</I>(<I>ty</I> * x); | |
383 | int <I>compare-fn</I>(<I>ty</I> * x, <I>ty</I> * y); | |
384 | long <I>hash-fn</I>(<I>ty</I> * x); | |
385 | </PRE> | |
386 | That is, their arguments are passed by reference. The comparison | |
387 | function must return an integer that is negative, zero, or positive | |
388 | depending on whether its first argument is smaller, equal or greater | |
389 | than its second argument. The hashing function returns a suitable | |
390 | hash value for its argument.<BR> | |
391 | <BR> | |
392 | If the <TT><FONT COLOR=blue>errorcheck(</FONT></TT><TT><I><FONT COLOR=maroon>fn</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> attribute is provided for the <TT>typedef</TT> <I>ty</I>, | |
393 | the error checking function <TT><I><FONT COLOR=maroon>fn</FONT></I></TT> is called each time a function result | |
394 | of type <I>ty</I> is converted from C to Caml. The function can then check | |
395 | the <I>ty</I> value for values indicating an error condition, and raise the | |
396 | appropriate exception. If in addition the <TT><FONT COLOR=blue>errorcode</FONT></TT> attribute is | |
397 | provided, the conversion from C to Caml is suppressed: values of type | |
398 | <I>ty</I> are only passed to <TT><I><FONT COLOR=maroon>fn</FONT></I></TT> for error checking, then discarded.<BR> | |
399 | <BR> | |
400 | <A NAME="toc19"></A> | |
401 | <H3><A NAME="htoc22">3.9</A> Functions</H3> | |
402 | IDL function declarations are translated to Caml functions. | |
403 | The parameters and results of the Caml function are determined from | |
404 | those of the IDL function according to the following rules: | |
405 | <UL><LI> | |
406 | First, dependent parameters (parameters that are <TT>size_is</TT>, | |
407 | <TT>length_is</TT> or <TT>switch_is</TT> of other parameters) as well as parameters | |
408 | that are ignored pointers are removed.<BR> | |
409 | <BR> | |
410 | <LI>The remaining parameters are split into Caml function inputs and | |
411 | Caml function outputs. Parameters with the <TT>[in]</TT> attribute are added | |
412 | to the inputs of the function. Parameters with the <TT>[out]</TT> | |
413 | attribute are added to the outputs of the function. Parameters with | |
414 | the <TT>[in,out]</TT> attribute are added both to the inputs and to the | |
415 | outputs of the function, unless they are of type string or big array, | |
416 | in which case they are added to the inputs of the function only. | |
417 | (The reason for this exception is that strings and big arrays are | |
418 | shared between Caml and C, thus allowing true <TT>in,out</TT> behavior on the | |
419 | Caml function parameter, while other data types are copied during | |
420 | Caml/C conversion, thus turning a C <TT>in,out</TT> parameter into a Caml | |
421 | <TT>copy in, copy out</TT> parameter, that is, one parameter and one result.)<BR> | |
422 | <BR> | |
423 | <LI>The return value of the IDL function is added to the outputs of | |
424 | the Caml function (in first position), unless it is of type <TT>void</TT> or | |
425 | of a type name that carries the <TT>errorcode</TT> attribute. In the latter | |
426 | two cases, the return value of the IDL function is not transmitted to | |
427 | Caml. | |
428 | <LI>The Caml function is then given type | |
429 | <TT><I><FONT COLOR=maroon>in</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> <TT><FONT COLOR=blue>-></FONT></TT> ... <TT><FONT COLOR=blue>-></FONT></TT> <TT><I><FONT COLOR=maroon>in</FONT></I></TT><SUB><FONT SIZE=2><I>p</I></FONT></SUB> <TT><FONT COLOR=blue>-></FONT></TT> <TT><I><FONT COLOR=maroon>out</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> <TT><FONT COLOR=blue>*</FONT></TT> ... <TT><FONT COLOR=blue>*</FONT></TT> <TT><I><FONT COLOR=maroon>out</FONT></I></TT><SUB><FONT SIZE=2><I>q</I></FONT></SUB> | |
430 | where <TT><I><FONT COLOR=maroon>in</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> ... <TT><I><FONT COLOR=maroon>in</FONT></I></TT><SUB><FONT SIZE=2><I>p</I></FONT></SUB> are the types of its inputs | |
431 | and <TT><I><FONT COLOR=maroon>out</FONT></I></TT><SUB><FONT SIZE=2>1</FONT></SUB> ... <TT><I><FONT COLOR=maroon>out</FONT></I></TT><SUB><FONT SIZE=2><I>q</I></FONT></SUB> are the types of its outputs. | |
432 | If there are no inputs, a <TT>unit</TT> parameter is added. | |
433 | If there are no outputs, a <TT>unit</TT> result is added. | |
434 | </UL> | |
435 | Examples: | |
436 | <PRE> | |
437 | int f([in] double x, [in] double y) f : float -> float -> int | |
438 | </PRE> | |
439 | <BLOCKQUOTE> Two <TT>double</TT> input, one <TT>int</TT> output </BLOCKQUOTE> | |
440 | <PRE> | |
441 | void g([in] int x) g : int -> unit | |
442 | </PRE> | |
443 | <BLOCKQUOTE> One <TT>int</TT> input, no output </BLOCKQUOTE> | |
444 | <PRE> | |
445 | int h() h : unit -> int | |
446 | </PRE> | |
447 | <BLOCKQUOTE> No input, one <TT>int</TT> result </BLOCKQUOTE> | |
448 | <PRE> | |
449 | void i([in] int x, [out] double * y) i : int -> double | |
450 | </PRE> | |
451 | <BLOCKQUOTE> One <TT>int</TT> input, one <TT>double</TT> output (as an <TT>out</TT> | |
452 | parameter) </BLOCKQUOTE> | |
453 | <PRE> | |
454 | int j([in] int x, [out] double * y) j : int -> int * double | |
455 | </PRE> | |
456 | <BLOCKQUOTE> One <TT>int</TT> input, one <TT>int</TT> output (in the result), one | |
457 | <TT>double</TT> output (as an <TT>out</TT> parameter) </BLOCKQUOTE> | |
458 | <PRE> | |
459 | void k([in,out,ref] int * x) k : int -> int | |
460 | </PRE> | |
461 | <BLOCKQUOTE> The <TT>in,out</TT> parameter is both one <TT>int</TT> input and one | |
462 | <TT>int</TT> output. </BLOCKQUOTE> | |
463 | <PRE> | |
464 | HRESULT l([in] int x, [out] int * res1, [out] int * res2) | |
465 | l : int -> int * int | |
466 | </PRE> | |
467 | <BLOCKQUOTE> <TT>HRESULT</TT> is a predefined type with the <TT>errorcode</TT> | |
468 | attribute, hence it is ignored. It remains one <TT>int</TT> input and | |
469 | two <TT>int</TT> outputs (<TT>out</TT> parameters) </BLOCKQUOTE> | |
470 | <PRE> | |
471 | void m([in] int len, [in,size_is(len)] double d[]) | |
472 | m : float array -> int | |
473 | </PRE> | |
474 | <BLOCKQUOTE> <TT>len</TT> is a dependent parameter, hence is ignored. The | |
475 | only input is the <TT>double</TT> array </BLOCKQUOTE> | |
476 | <PRE> | |
477 | void n([in] int inputlen, [out] int * outputlen, | |
478 | [in,out,size_is(inputlen),length_is(*outputlen)] double d[]) | |
479 | n : float array -> float array | |
480 | </PRE> | |
481 | <BLOCKQUOTE> The two parameters <TT>inputlen</TT> and <TT>outputlen</TT> are | |
482 | dependent, hence ignored. The <TT>double</TT> array is both an input | |
483 | and an output. </BLOCKQUOTE> | |
484 | <PRE> | |
485 | void p([in] int dimx, [in] int dimy, | |
486 | [in,out,bigarray,size_is(dimx,dimy)] double d[][]) | |
487 | p : (float, Bigarray.float64_elt, Bigarray.c_layout) Bigarray.Array2.t -> unit | |
488 | </PRE> | |
489 | <BLOCKQUOTE> The two parameters <TT>dimx</TT> and <TT>dimy</TT> are dependent | |
490 | (determined from the dimensions of the big array argument), | |
491 | hence ignored. The two-dimensional array <TT>d</TT>, although marked <TT>[in,out]</TT>, | |
492 | is a big array, hence passed as an input that will be modified in | |
493 | place by the C function <TT>p</TT>. The Caml function has no outputs. | |
494 | </BLOCKQUOTE> | |
495 | ||
496 | <H5>Error checking:</H5> | |
497 | For every output that is of a named type with the <TT><FONT COLOR=blue>errorcheck(</FONT></TT><TT><I><FONT COLOR=maroon>fn</FONT></I></TT><TT><FONT COLOR=blue>)</FONT></TT> | |
498 | attribute, the error checking function <TT><I><FONT COLOR=maroon>fn</FONT></I></TT> is called after the C | |
499 | function returns. That function is assumed to raise a Caml exception | |
500 | if it finds an output denoting an error.<BR> | |
501 | <BR> | |
502 | ||
503 | <H5>Custom calling and deallocation sequences:</H5> | |
504 | The IDL declaration for a function can optionally specify a custom | |
505 | calling sequence and/or a custom deallocation sequence, via <TT><I><FONT COLOR=maroon>quote</FONT></I></TT> | |
506 | clauses following the function declaration: | |
507 | <DIV ALIGN=center><TABLE CELLSPACING=2 CELLPADDING=0> | |
508 | <TR><TD ALIGN=right NOWRAP> | |
509 | <TT><I><FONT COLOR=maroon>function-decl</FONT></I></TT></TD> | |
510 | <TD ALIGN=right NOWRAP>::=</TD> | |
511 | <TD ALIGN=left NOWRAP> | |
512 | <TT><I><FONT COLOR=maroon>attributes</FONT></I></TT> <TT><I><FONT COLOR=maroon>type-spec</FONT></I></TT> {<TT><FONT COLOR=blue>*</FONT></TT>} <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>params</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> | |
513 | { <TT><FONT COLOR=blue>quote</FONT></TT><TT><FONT COLOR=blue>(</FONT></TT> <TT><I><FONT COLOR=maroon>ident</FONT></I></TT> <TT><FONT COLOR=blue>,</FONT></TT> <TT><I><FONT COLOR=maroon>string</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> }</TD> | |
514 | </TR></TABLE></DIV> | |
515 | The general shape of a <TT>camlidl</TT>-generated stub function is as | |
516 | follows: | |
517 | <PRE> | |
518 | value caml_wrapper(value camlparam1, ..., value camlparamK) | |
519 | ||
520 | /* Convert the function parameters from Caml to C */ | |
521 | param1 = ...; | |
522 | ... | |
523 | paramN = ...; | |
524 | /* Call the C function 'ident' */ | |
525 | _res = ident(param1, ..., paramN); | |
526 | /* Convert the function result and out parameters to Caml values */ | |
527 | camlres = ...; | |
528 | /* Return result to Caml */ | |
529 | return camlres; | |
530 | ||
531 | </PRE> | |
532 | A <TT><FONT COLOR=blue>quote(call,</FONT></TT> <TT><I><FONT COLOR=maroon>string</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> clause causes the C statements in | |
533 | <TT><I><FONT COLOR=maroon>string</FONT></I></TT> to be inserted in the generated stub code | |
534 | instead of the default calling sequence <TT>_res = ident(param1, ..., paramN)</TT>. | |
535 | Thus, the statements in <TT><I><FONT COLOR=maroon>string</FONT></I></TT> find the converted parameters in | |
536 | local variables that have the same names as the parameters in the IDL | |
537 | declaration, and should leave the result of the function, if any, in | |
538 | the local variable named <TT>_res</TT>.<BR> | |
539 | <BR> | |
540 | A <TT><FONT COLOR=blue>quote(dealloc,</FONT></TT> <TT><I><FONT COLOR=maroon>string</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> clause causes the C statements in | |
541 | <TT><I><FONT COLOR=maroon>string</FONT></I></TT> to be inserted in the generated stub code just before the | |
542 | stub function returns, hence after the conversion of the C function | |
543 | results to Caml values. Again, the statements in <TT><I><FONT COLOR=maroon>string</FONT></I></TT> have access | |
544 | to the function result in the local variable named <TT>_res</TT>, and to out | |
545 | parameters in local variables having the same names as the | |
546 | parameters. Since the function results and out parameters have | |
547 | already been converted to Caml values, the code in <TT><I><FONT COLOR=maroon>string</FONT></I></TT> can safely | |
548 | deallocate the data structures they point to.<BR> | |
549 | <BR> | |
550 | Custom calling sequences are typically used to rearrange or combine | |
551 | function parameters, and to perform extra error checks on the | |
552 | arguments and results. For instance, the Unix <TT>write</TT> system call can | |
553 | be specified in IDL as follows: | |
554 | <PRE> | |
555 | int write([in] int fd, | |
556 | [in,string,length_is(len)] char * data, | |
557 | [in] int len, | |
558 | [in] int ofs, | |
559 | [in] int towrite) | |
560 | quote(call, | |
561 | " /* Validate the arguments */ | |
562 | if (ofs < 0 || ofs + towrite >= len) failwith(\"write\"); | |
563 | /* Perform the write */ | |
564 | _res = write(fd, data + ofs, towrite); | |
565 | /* Validate the result */ | |
566 | if (_res == -1) failwith(\"write\"); "); | |
567 | </PRE>Custom deallocation sequences are useful to free data structures | |
568 | dynamically allocated and returned by the C function. For instance, | |
569 | a C function <TT>f</TT> that returns a <TT>malloc</TT>-ed string can be specified in | |
570 | IDL as follows: | |
571 | <PRE> | |
572 | [string] char * f([in] int x) | |
573 | quote(dealloc, "free(_res); "); | |
574 | </PRE>If the string is returned as an <TT>out</TT> parameter instead, we would write: | |
575 | <PRE> | |
576 | void f ([in] int x, [out, string*] char ** str) | |
577 | quote(dealloc, "free(*str); "); | |
578 | </PRE> | |
579 | <A NAME="toc20"></A> | |
580 | <H3><A NAME="htoc23">3.10</A> Interfaces</H3> | |
581 | IDL interfaces that do not have the <TT><FONT COLOR=blue>object</FONT></TT> attribute are | |
582 | essentially ignored. That is, the declarations contained in the | |
583 | interface are processed as if they occurred at the top-level of the | |
584 | IDL file. The <TT><FONT COLOR=blue>pointer_default</FONT></TT>, <TT><FONT COLOR=blue>int_default</FONT></TT> and | |
585 | <TT><FONT COLOR=blue>long_default</FONT></TT> attributes to the interface can be | |
586 | used to specify the default pointer kind and integer mappings | |
587 | for the declarations contained in the interface. Other attributes, as | |
588 | well as the name of the super-interface if any, are ignored.<BR> | |
589 | <BR> | |
590 | IDL interfaces having the <TT><FONT COLOR=blue>object</FONT></TT> attribute specify COM-style object | |
591 | interfaces. The function declarations contained in the interface | |
592 | specify the methods of the COM interface. Other kinds of declarations | |
593 | (type declarations, <TT><FONT COLOR=blue>import</FONT></TT> statements, etc) are treated as if they | |
594 | occurred at the top-level of the IDL file. An optional | |
595 | super-interface can be given, in which case the COM interface | |
596 | implements the methods of the super-interface in addition to those | |
597 | specified in the IDL interface. | |
598 | Example: | |
599 | <PRE> | |
600 | [object, uuid(...)] interface IA { typedef int t; int f(int x); } | |
601 | [object] interface IB : IA { import "foo.idl"; void g([string] char * s); } | |
602 | </PRE>This defines a type <TT>t</TT> and imports the file <TT>foo.idl</TT> as usual. In | |
603 | addition, two interfaces are declared: <TT>IA</TT>, containing one | |
604 | method <TT>f</TT> from <TT>int</TT> to <TT>int</TT>, and <TT>IB</TT>, containing | |
605 | two methods, <TT>f</TT> from <TT>int</TT> to <TT>int</TT> and <TT>g</TT> from <TT>string</TT> to <TT>unit</TT>.<BR> | |
606 | <BR> | |
607 | The definition of an object interface <I>i</I> generates the following | |
608 | Caml definitions: | |
609 | <UL><LI> | |
610 | An abstract type <I>i</I> identifying the interface. | |
611 | COM interfaces of type <I>i</I> are represented in Caml | |
612 | with type <I>i</I> <TT> Com.interface</TT>. | |
613 | <LI>If a super-interface <I>s</I> is given, a conversion function | |
614 | <I>s</I><TT>_of_</TT><I>i</I> of type | |
615 | <I>i</I> <TT> Com.interface -> </TT> <I>s</I> <TT> Com.interface</TT>. | |
616 | <LI>If the <TT>uuid(</TT><I>iid</I><TT>)</TT> attribute is given, a value | |
617 | <TT>iid_</TT><I>i</I> of type <I>i</I><TT> Com.iid</TT> holding the given interface | |
618 | identifier. | |
619 | <LI>A Caml class <I>i</I><TT>_class</TT>, with the same methods as the COM | |
620 | interface. | |
621 | <LI>A function <TT>use_</TT><I>i</I> of type <I>i</I> <TT> Com.interface -> </TT><I>i</I><TT>_class</TT>, to transform a COM object into a Caml object. This | |
622 | allows the methods of the COM object to be invoked from Caml. | |
623 | <LI>A function <TT>make_</TT><I>i</I> of type <TT>#</TT><I>i</I><TT>_class -> </TT><I>i</I> | |
624 | <TT> Com.interface</TT>, to transform a Caml object into a COM object with | |
625 | interface <I>i</I>. This allows the methods of the Caml object to be | |
626 | invoked from any COM client. | |
627 | </UL> | |
628 | Example: in the <TT>IA</TT> and <TT>IB</TT> example above, the following Caml | |
629 | definitions are generated for <TT>IA</TT>: | |
630 | <PRE> | |
631 | type iA | |
632 | val iid_iA : iA Com.iid | |
633 | class iA_class : iA Com.interface -> object method f : int -> int end | |
634 | val use_iA : iA Com.interface -> iA_class | |
635 | val make_iA : #iA_class -> iA Com.interface | |
636 | </PRE>For <TT>IB</TT>, we get: | |
637 | <PRE> | |
638 | type iB | |
639 | val iA_of_iB : iB Com.interface -> iA Com.interface | |
640 | class iB_class : | |
641 | iB Com.interface -> object inherit iA_class method g : string -> unit end | |
642 | val use_iB : iB Com.interface -> iB_class | |
643 | val make_iB : #iB_class -> iB Com.interface | |
644 | </PRE> | |
645 | ||
646 | <H5>Error handling in interfaces:</H5> Conventionally, methods of | |
647 | COM interfaces always return a result of type <TT>HRESULT</TT> that says | |
648 | whether the method succeeded or failed, and in the latter case returns | |
649 | an error code to its caller.<BR> | |
650 | <BR> | |
651 | When calling an interface method from Caml, if the method returns an | |
652 | <TT>HRESULT</TT> denoting failure, the exception <TT>Com.Error</TT> is raised with a | |
653 | message describing the error. Successful <TT>HRESULT</TT> return values are | |
654 | ignored. To make them available to Caml, <TT>camlidl</TT> defines the types | |
655 | <TT>HRESULT_bool</TT> and <TT>HRESULT_int</TT>. If those types are used as return | |
656 | types instead of <TT>HRESULT</TT>, failure results are mapped to | |
657 | <TT>Com.Error</TT> exceptions as before, but successful results are mapped to | |
658 | the Caml types <TT>bool</TT> and <TT>int</TT> respectively. (For <TT>HRESULT_bool</TT>, | |
659 | the <TT>S_OK</TT> result is mapped to <TT>true</TT> and other successful results are | |
660 | mapped to <TT>false</TT>. For <TT>HRESULT_int</TT>, the low 16 bits of the result | |
661 | code are returned as a Caml <TT>int</TT>.)<BR> | |
662 | <BR> | |
663 | When calling a Caml method from a COM client, any exception that | |
664 | escapes the Caml method is mapped back to a failure <TT>HRESULT</TT>. A | |
665 | textual description of the uncaught exception is saved using | |
666 | <TT>SetLastError</TT>, and can be consulted by the COM client using | |
667 | <TT>GetLastError</TT> (this is the standard convention for passing extended | |
668 | error information in COM).<BR> | |
669 | <BR> | |
670 | If the IDL return type of the method is not one of the <TT>HRESULT</TT> | |
671 | types, any exception escaping the Caml method aborts the whole program | |
672 | after printing a description of the exception. Hence, programmers of | |
673 | Caml components should either use <TT>HRESULT</TT> as result type, or make | |
674 | very sure that all exceptions are properly caught by the method.<BR> | |
675 | <BR> | |
676 | <HR> | |
677 | <A HREF="main002.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
678 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
679 | <A HREF="main004.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
680 | </BODY> | |
681 | </HTML> |
0 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | |
1 | "http://www.w3.org/TR/REC-html40/loose.dtd"> | |
2 | <HTML> | |
3 | <HEAD> | |
4 | ||
5 | <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
6 | <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> | |
7 | <TITLE> | |
8 | Using camlidl | |
9 | </TITLE> | |
10 | </HEAD> | |
11 | <BODY > | |
12 | <A HREF="main003.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
13 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
14 | <A HREF="main005.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
15 | <HR> | |
16 | ||
17 | <H2><A NAME="htoc24">4</A> Using <TT>camlidl</TT></H2> | |
18 | <A NAME="toc21"></A> | |
19 | <H3><A NAME="htoc25">4.1</A> Overview</H3> | |
20 | The <TT>camlidl</TT> stub generator is invoked as follows: | |
21 | <PRE> | |
22 | camlidl <I>options</I> <I>file1</I>.idl <I>file2</I>.idl ... | |
23 | </PRE> | |
24 | For each file <I>f</I><TT>.idl</TT> given on the command line, <TT>camlidl</TT> | |
25 | generates the following files: | |
26 | <UL><LI> | |
27 | A Caml interface file <I>f</I><TT>.mli</TT> that defines the Caml view | |
28 | of the IDL file. It contains Caml definitions for the types declared | |
29 | in the IDL file, as well as declarations for the functions and the | |
30 | interfaces. | |
31 | <LI>A Caml implementation file <I>f</I><TT>.ml</TT> that implements the | |
32 | <I>f</I><TT>.mli</TT> file. | |
33 | <LI>A C source file <I>f</I><TT>_stubs.c</TT> that contains the stub functions for | |
34 | converting between C and Caml data representations. | |
35 | <LI>If the <TT>-header</TT> option is given, a C header file <I>f</I><TT>.h</TT> | |
36 | containing C declarations for the types declared in the IDL file. | |
37 | </UL> | |
38 | The generated <TT>.ml</TT> and <TT>.c</TT> files must be compiled and linked with | |
39 | the remainder of the Caml program.<BR> | |
40 | <BR> | |
41 | <A NAME="toc22"></A> | |
42 | <H3><A NAME="htoc26">4.2</A> Options</H3> | |
43 | The following command-line options are recognized by <TT>camlidl</TT>. | |
44 | <DL COMPACT=compact><DT><B><TT>-cpp</TT></B><DD> | |
45 | Pre-process the source IDL files with the C preprocessor. This option | |
46 | is set by default.<BR> | |
47 | <BR> | |
48 | <DT><B><TT>-D </TT> <I>symbol</I></B><B><TT>=</TT><I>value</I></B><DD> | |
49 | Define a preprocessor symbol. The option <TT>-D</TT><I>symbol</I><TT>=</TT><I>value</I> | |
50 | is passed to the C preprocessor. The <I>value</I> can be omitted, | |
51 | as in <TT>-D</TT> <I>symbol</I>, and defaults to <TT>1</TT>.<BR> | |
52 | <BR> | |
53 | <DT><B><TT>-header</TT></B><DD> | |
54 | Generate a C header file <I>f</I><TT>.h</TT> containing C declarations for the | |
55 | types and functions declared in the IDL file <I>f</I><TT>.c</TT>.<BR> | |
56 | <BR> | |
57 | <DT><B><TT>-I </TT> <I>dir</I></B><DD> | |
58 | Add the directory <I>dir</I> to the list of directories searched for | |
59 | <TT>.idl</TT> files, as given on the command line or recursively loaded | |
60 | by <TT><FONT COLOR=blue>import</FONT></TT> statements.<BR> | |
61 | <BR> | |
62 | <DT><B><TT>-keep-labels</TT></B><DD> | |
63 | Keep the Caml names of record labels as specified in the IDL file. | |
64 | Do not prefix them with the name of the enclosing struct, even if they | |
65 | appear in several struct definitions.<BR> | |
66 | <BR> | |
67 | <DT><B><TT>-nocpp</TT></B><DD> | |
68 | Suppresses the pre-processing of source IDL files.<BR> | |
69 | <BR> | |
70 | <DT><B><TT>-no-include</TT></B><DD> | |
71 | By default, <TT>camlidl</TT> emits a <TT>#include "</TT><I>f</I><TT>.h"</TT> statement in | |
72 | the file <I>f</I><TT>.c</TT> containing the generated C code. | |
73 | The <I>f</I><TT>.h</TT> header file being included is | |
74 | either the one generated by <TT>camlidl -header</TT>, or generated by another | |
75 | tool (such as Microsoft's <TT>midl</TT> compiler) from the IDL file, or | |
76 | hand-written. The <I>f</I><TT>.h</TT> file is assumed to provide all C type | |
77 | declarations needed for compiling the stub code.<BR> | |
78 | <BR> | |
79 | The <TT>-no-include</TT> option suppresses the automatic inclusion of the | |
80 | <I>f</I><TT>.h</TT> file. The IDL file should then include the right header | |
81 | files and provide the right type declarations via <TT><FONT COLOR=blue>quote</FONT></TT> statements.<BR> | |
82 | <BR> | |
83 | <DT><B><TT>-prefix-all-labels</TT></B><DD> | |
84 | Prefix all Caml names of record labels with the name of the enclosing | |
85 | struct. The default is to prefix only those labels that could cause | |
86 | ambiguity because they appear in several struct definitions.<BR> | |
87 | <BR> | |
88 | <DT><B><TT>-prepro</TT> <I>preprocessing-command</I></B><DD> | |
89 | Set the command that is executed to pre-process the source IDL files. | |
90 | The default is the C preprocessor.</DL> | |
91 | <A NAME="toc23"></A> | |
92 | <H3><A NAME="htoc27">4.3</A> The <TT>camlidldll</TT> script</H3> | |
93 | Under Windows, a <TT>bash</TT> script called <TT>camlidldll</TT> is provided to | |
94 | automate the construction of a DLL containing a COM component written | |
95 | in Caml.<BR> | |
96 | <BR> | |
97 | The script <TT>camlidldll</TT> accepts essentially the same command-line | |
98 | arguments and options as the <TT>ocamlc</TT> compiler. (It also accepts | |
99 | <TT>.tlb</TT> type library files on the command-line; see | |
100 | section <A HREF="main006.html#s-dispatch">6.3</A>, ``Dispatch interfaces'', for more | |
101 | information on type libraries.) | |
102 | It produces a DLL file that encapsulates the Caml and C object files | |
103 | given on the command line.<BR> | |
104 | <BR> | |
105 | Use <TT>regsvr32 /s </TT><I>file</I><TT>.dll</TT> to record the components in the | |
106 | system registry once it is compiled to a DLL.<BR> | |
107 | <BR> | |
108 | <HR> | |
109 | <A HREF="main003.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
110 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
111 | <A HREF="main005.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
112 | </BODY> | |
113 | </HTML> |
0 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | |
1 | "http://www.w3.org/TR/REC-html40/loose.dtd"> | |
2 | <HTML> | |
3 | <HEAD> | |
4 | ||
5 | <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
6 | <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> | |
7 | <TITLE> | |
8 | Module Com: run-time library for COM components | |
9 | </TITLE> | |
10 | </HEAD> | |
11 | <BODY > | |
12 | <A HREF="main004.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
13 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
14 | <A HREF="main006.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
15 | <HR> | |
16 | ||
17 | <H2><A NAME="htoc28">5</A> Module <TT>Com</TT>: run-time library for COM components</H2> | |
18 | <A NAME="s:Com"></A> | |
19 | ||
20 | <PRE> | |
21 | type 'a interface | |
22 | </PRE><BLOCKQUOTE> | |
23 | The type of COM components implementing interface <CODE>'a</CODE> | |
24 | </BLOCKQUOTE> | |
25 | <PRE> | |
26 | type 'a iid | |
27 | </PRE><BLOCKQUOTE> | |
28 | The type of the interface identifier for interface <CODE>'a</CODE> | |
29 | </BLOCKQUOTE> | |
30 | <PRE> | |
31 | type clsid | |
32 | </PRE><BLOCKQUOTE> | |
33 | The type of component identifiers | |
34 | </BLOCKQUOTE> | |
35 | <PRE> | |
36 | type 'a opaque | |
37 | </PRE><BLOCKQUOTE> | |
38 | The type representing opaque pointers to values of type <CODE>'a</CODE>. | |
39 | Opaque pointers are pointers with attribute <CODE>ptr</CODE> in IDL files. | |
40 | </BLOCKQUOTE> | |
41 | <PRE> | |
42 | exception Error of int * string * string | |
43 | </PRE><BLOCKQUOTE> | |
44 | Exception raised to report Com errors. | |
45 | The arguments are <CODE>Error(errcode, who, what)</CODE>. | |
46 | <CODE>errcode</CODE> is the Com error code (<CODE>HRESULT</CODE> code) | |
47 | with the high bit clear. | |
48 | <CODE>who</CODE> identifies the function or method that raised the exception. | |
49 | <CODE>what</CODE> is a message explaining the cause of the error. | |
50 | </BLOCKQUOTE> | |
51 | <PRE> | |
52 | val initialize : unit -> unit | |
53 | </PRE><BLOCKQUOTE> | |
54 | Initialize the COM library. Must be called once before | |
55 | using any function in this module. <CODE>Com.initialize</CODE> | |
56 | can be called several times, provided that <CODE>Com.uninitialize</CODE> | |
57 | is called an equal number of times before the program exits. | |
58 | </BLOCKQUOTE> | |
59 | <PRE> | |
60 | val uninitialize : unit -> unit | |
61 | </PRE><BLOCKQUOTE> | |
62 | Terminate the COM library. | |
63 | </BLOCKQUOTE> | |
64 | <PRE> | |
65 | val query_interface : 'a interface -> 'b iid -> 'b interface | |
66 | </PRE><BLOCKQUOTE> | |
67 | <CODE>Com.query_interface comp iid</CODE> asks the component <CODE>comp</CODE> | |
68 | whether it supports the interface identified by <CODE>iid</CODE>. | |
69 | If yes, it returns the corresponding interface of the component. | |
70 | If not, it raises <CODE>Com.Error</CODE>. | |
71 | </BLOCKQUOTE> | |
72 | <PRE> | |
73 | type iUnknown | |
74 | </PRE><BLOCKQUOTE> | |
75 | The type of the interface <CODE>IUnknown</CODE>, from which all other | |
76 | interfaces derive. | |
77 | </BLOCKQUOTE> | |
78 | <PRE> | |
79 | type iDispatch | |
80 | </PRE><BLOCKQUOTE> | |
81 | The type of the interface <CODE>IDispatch</CODE>, from which all | |
82 | dispatch interfaces derive. | |
83 | </BLOCKQUOTE> | |
84 | <PRE> | |
85 | val iUnknown_of : 'a interface -> iUnknown interface | |
86 | </PRE><BLOCKQUOTE> | |
87 | Return the <CODE>IUnknown</CODE> interface of the given component. | |
88 | This operation never fails, since all components support | |
89 | the <CODE>IUnknown</CODE> interface. | |
90 | </BLOCKQUOTE> | |
91 | <PRE> | |
92 | val combine : 'a interface -> 'b interface -> 'a interface | |
93 | </PRE><BLOCKQUOTE> | |
94 | Combine the interfaces of two components. | |
95 | <CODE>Com.combine c1 c2</CODE> returns a component that supports the | |
96 | union of the interfaces supported by <CODE>c1</CODE> and <CODE>c2</CODE>. | |
97 | When queried for an interface, the resulting component | |
98 | delegates its implementation to <CODE>c1</CODE> if <CODE>c1</CODE> implements that | |
99 | interface, and otherwise delegates its implementation to <CODE>c2</CODE>. | |
100 | </BLOCKQUOTE> | |
101 | <PRE> | |
102 | val clsid : string -> clsid | |
103 | </PRE><BLOCKQUOTE> | |
104 | Parse the string representation of a component identifier | |
105 | (<CODE>hex8-hex4-hex4-hex4-hex12</CODE>, where <CODE>hexN</CODE> represents <CODE>N</CODE> | |
106 | hexadecimal digits). | |
107 | </BLOCKQUOTE> | |
108 | <PRE> | |
109 | val create_instance : clsid -> 'a iid -> 'a interface | |
110 | </PRE><BLOCKQUOTE> | |
111 | <CODE>Com.create_instance clsid iid</CODE> creates an instance of | |
112 | the component identified by <CODE>clsid</CODE>, and returns its <CODE>iid</CODE> | |
113 | interface. The implementation of the component is searched | |
114 | in the registry; if the component is implemented in a DLL, | |
115 | the DLL is loaded in memory if necessary; if the component | |
116 | is implemented in a separate server process, the server is | |
117 | started if necessary. Raise <CODE>Com.Error</CODE> if the component | |
118 | <CODE>clsid</CODE> cannot be found, or if it does not support interface | |
119 | <CODE>iid</CODE>. | |
120 | </BLOCKQUOTE> | |
121 | <PRE> | |
122 | type 'a component_factory = | |
123 | { create : unit -> 'a interface; | |
124 | clsid : clsid; | |
125 | friendly_name : string; | |
126 | ver_ind_prog_id : string; | |
127 | prog_id : string } | |
128 | </PRE><BLOCKQUOTE> | |
129 | Informations required for registering a Caml implementation | |
130 | of a component. | |
131 | <CODE>create</CODE> is a function that returns a fresh instance | |
132 | of the component. | |
133 | <CODE>clsid</CODE> is the component identifier. | |
134 | <CODE>friendly_name</CODE> is a short description of the component | |
135 | (for information only). | |
136 | <CODE>ver_ind_prog_id</CODE> and <CODE>prog_id</CODE> are symbolic names for the | |
137 | component. By convention, <CODE>prog_id</CODE> is <CODE>ver_ind_prog_id</CODE> plus | |
138 | a version number at the end, i.e. <CODE>ver_ind_prog_id</CODE> is | |
139 | <CODE>"MyCamlComponent"</CODE> while <CODE>prog_id</CODE> is <CODE>"MyCamlComponent.3"</CODE>. | |
140 | </BLOCKQUOTE> | |
141 | <PRE> | |
142 | val register_factory : 'a component_factory -> unit | |
143 | </PRE><BLOCKQUOTE> | |
144 | Register a Caml implementation of a component. | |
145 | <CODE>Com.register_factory f</CODE> stores the component factory <CODE>f</CODE> | |
146 | in the registry. Other programs can then create instances | |
147 | of the component by calling <CODE>CreateInstance</CODE> from C and C++ | |
148 | or <CODE>Com.create_instance</CODE> from Caml. | |
149 | </BLOCKQUOTE> | |
150 | <PRE> | |
151 | type hRESULT_int = int | |
152 | type hRESULT_bool = bool | |
153 | type bSTR = string | |
154 | </PRE><BLOCKQUOTE> | |
155 | The Caml types corresponding to the IDL types <CODE>HRESULT_int</CODE>, | |
156 | <CODE>HRESULT_bool</CODE> and <CODE>BSTR</CODE>, respectively. | |
157 | </BLOCKQUOTE> | |
158 | ||
159 | <HR> | |
160 | <A HREF="main004.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
161 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
162 | <A HREF="main006.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
163 | </BODY> | |
164 | </HTML> |
0 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | |
1 | "http://www.w3.org/TR/REC-html40/loose.dtd"> | |
2 | <HTML> | |
3 | <HEAD> | |
4 | ||
5 | <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
6 | <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> | |
7 | <TITLE> | |
8 | Hints on writing IDL files | |
9 | </TITLE> | |
10 | </HEAD> | |
11 | <BODY > | |
12 | <A HREF="main005.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
13 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
14 | <A HREF="main007.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
15 | <HR> | |
16 | ||
17 | <H2><A NAME="htoc29">6</A> Hints on writing IDL files</H2> | |
18 | <A NAME="toc24"></A> | |
19 | <H3><A NAME="htoc30">6.1</A> Writing an IDL file for a C library</H3> | |
20 | When writing an IDL file for a C library that doesn't have an IDL interface | |
21 | already, the include files for that library are a good starting point: | |
22 | just copy the relevant type and functin declarations to the IDL file, | |
23 | then annotate them with IDL attributes to describe more precisely | |
24 | their actual behavior. The documentation of the library must be read | |
25 | carefully to determine the mode of function parameters (<TT>in</TT>, <TT>out</TT>, | |
26 | <TT>inout</TT>), the actual sizes of arrays, etc.<BR> | |
27 | <BR> | |
28 | The type definitions in the IDL file need not correspond exactly with | |
29 | those in the include files. Often, a cleaner Caml interface can be | |
30 | obtained by omitting irrelevant struct fields, or changing their types. | |
31 | For instance, the Unix library functions for reading library entries | |
32 | may use the following structure: | |
33 | <PRE> | |
34 | struct dirent { | |
35 | long int d_ino; | |
36 | __off_t d_off; | |
37 | unsigned short int d_reclen; | |
38 | unsigned char d_type; | |
39 | char d_name[256]; | |
40 | }; | |
41 | </PRE>Of those fields, only <TT>d_name</TT> and <TT>d_ino</TT> are of interest to the | |
42 | user; the other fields are internal information for the library | |
43 | functions, are not specified in the POSIX specs, and therefore must | |
44 | not be used. Thus, in the IDL file, you should declare: | |
45 | <PRE> | |
46 | struct dirent { | |
47 | long int d_ino; | |
48 | char d_name[256]; | |
49 | }; | |
50 | </PRE>Thus, the Caml code will have | |
51 | <TT>type struct_dirent = {d_ino: int; d_name: string}</TT> | |
52 | as desired. However, the generated stub code, being | |
53 | compiled against the ``true'' definition of <TT>struct dirent</TT>, will find | |
54 | those two fields at the correct offsets in the actual struct.<BR> | |
55 | <BR> | |
56 | Special attention must be paid to integer fields or variables. | |
57 | By default, integer IDL types are mapped to the Caml type <TT>int</TT>, | |
58 | which is convenient to use in Caml code, but loses one bit | |
59 | when converting from a C <TT>long</TT> integer, and may lose one bit (on | |
60 | 32-bit platforms) when converting from a C <TT>int</TT> integer. When the | |
61 | range of values represented by the C integer is small enough, this | |
62 | loss is acceptable. Otherwise, you should use the attributes | |
63 | <TT>nativeint</TT>, <TT>int32</TT> or <TT>int64</TT> so that integer IDL types are mapped | |
64 | to one of the Caml boxed integer types. (We recommend that you use | |
65 | <TT>int32</TT> or <TT>int64</TT> for integers that are specified as being exactly 32 | |
66 | bit wide or 64 bit wide, and <TT>nativeint</TT> for unspecified <TT>int</TT> or | |
67 | <TT>long</TT> integers.)<BR> | |
68 | <BR> | |
69 | Yet another possibility is to declare certain integer fields or variables | |
70 | as <TT>double</TT> in the IDL file, so that they are represented by <TT>float</TT> | |
71 | in Caml, and all 32 bits of the integer are preserved in Caml. For | |
72 | instance, the Unix function to get the current type is declared as | |
73 | <PRE> | |
74 | time_t time(time_t * t); | |
75 | </PRE>where <TT>time_t</TT> is usually defined as <TT>long</TT>. We can nonetheless | |
76 | pretend (in the IDL file) that <TT>time</TT> returns a double: | |
77 | <PRE> | |
78 | double time() quote(" _res = time(NULL); "); | |
79 | </PRE>This way, <TT>time</TT> will have the Caml type <TT>unit -> float</TT>. | |
80 | Again, the stub code ``knows'' that <TT>time</TT> actually returns an integer, | |
81 | and therefore will insert the right integer-float coercions.<BR> | |
82 | <BR> | |
83 | <A NAME="toc25"></A> | |
84 | <H3><A NAME="htoc31">6.2</A> Sharing IDL files between MIDL and CamlIDL</H3> | |
85 | The Microsoft software development kit provides a number of IDL files | |
86 | describing various libraries and components. In its current state, | |
87 | <TT>camlidl</TT> cannot exploit those files directly: they use many | |
88 | (often poorly documented) Microsoft IDL features that are not | |
89 | implemented yet in <TT>camlidl</TT>; symmetrically, <TT>camlidl</TT> introduces | |
90 | several new annotations that are not recognized by Microsoft's <TT>midl</TT> | |
91 | compiler. So, significant editing work on the IDL files is required.<BR> | |
92 | <BR> | |
93 | The C preprocessor can be used to alleviate the <TT>camlidl</TT>-<TT>midl</TT> | |
94 | incompatibilities: <TT>camlidl</TT> defines the preprocessor symbol <TT>CAMLIDL</TT> | |
95 | when preprocessing its input files, while <TT>midl</TT> does not. Hence, | |
96 | one can bracket incompatible definitions in | |
97 | <TT>#ifdef CAMLIDL ... #else ... #endif</TT>. Along these lines, a C | |
98 | preprocessor header file, <TT>camlidlcompat.h</TT>, is provided: it uses | |
99 | <TT>#define</TT> to remove <TT>camlidl</TT>-specific attributes when compiling with | |
100 | <TT>midl</TT>, and to remove <TT>midl</TT>-specific attributes when compiling with | |
101 | <TT>camlidl</TT>. Thus, an IDL file compatible with both <TT>midl</TT> and | |
102 | <TT>camlidl</TT> would look like this: | |
103 | <PRE> | |
104 | #include <camlidlcompat.h> | |
105 | ||
106 | #ifndef CAMLIDL | |
107 | import "unknwn.idl"; // imports specific to MIDL | |
108 | import "oaidl.idl"; | |
109 | #endif | |
110 | import "mymodule.idl"; // imports common to MIDL and CamlIDL | |
111 | ||
112 | typedef [abstract,marshal_as(int)] void * ptr; | |
113 | ||
114 | ... | |
115 | ||
116 | #ifndef CAMLIDL | |
117 | [...] library MyTypeLib { | |
118 | importlib("stdole32.tlb"); | |
119 | [...] coclass MyComponent { [default] interface IX; } | |
120 | } | |
121 | #endif | |
122 | </PRE>Notice that since <TT>camlidl</TT> doesn't handle type libraries, the type | |
123 | library part of an <TT>midl</TT> file must be enclosed in <TT>#ifndef CAMLIDL</TT>.<BR> | |
124 | <BR> | |
125 | <A NAME="toc26"></A> | |
126 | <H3><A NAME="htoc32">6.3</A> Dispatch interfaces and type libraries</H3> <A NAME="s-dispatch"></A> | |
127 | A dispatch interface, in COM lingo, is an interface that supports | |
128 | dynamic, interpreted dispatch of method interfaces. This form of | |
129 | interpreted dispatch is used by Visual Basic and other scripting | |
130 | languages to perform calls to methods of COM components.<BR> | |
131 | <BR> | |
132 | CamlIDL provides minimal support for dispatch interfaces. To equip a | |
133 | Caml component with a dispatch interface (thus making it callable from | |
134 | Visual Basic), you need to do the following: | |
135 | <OL type=1><LI> | |
136 | Use <TT>IDispatch</TT> instead of <TT>IUnknown</TT> as the super-interface of | |
137 | the component's interfaces. | |
138 | <LI>Write a type library for your component and compile it using | |
139 | <TT>midl</TT>. A type library is a run-time representation of the interfaces | |
140 | supported by an object. The <TT>midl</TT> compiler can generate a type | |
141 | library from the IDL description of the component, enriched with some | |
142 | special-purpose declarations (the <TT>library</TT> and <TT>coclass</TT> | |
143 | statements). Refer to the documentation of <TT>midl</TT> for more | |
144 | information. | |
145 | <LI>Pass the type library files (<TT>.tlb</TT> files) generated by <TT>midl</TT> | |
146 | as extra arguments to <TT>camlidldll</TT> when generating the DLL for your | |
147 | Caml component. | |
148 | </OL> | |
149 | <HR> | |
150 | <A HREF="main005.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
151 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
152 | <A HREF="main007.html"><IMG SRC ="next_motif.gif" ALT="Next"></A> | |
153 | </BODY> | |
154 | </HTML> |
0 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" | |
1 | "http://www.w3.org/TR/REC-html40/loose.dtd"> | |
2 | <HTML> | |
3 | <HEAD> | |
4 | ||
5 | <META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | |
6 | <META name="GENERATOR" content="hevea 1.06-7 of 2001-11-14"> | |
7 | <TITLE> | |
8 | Release notes | |
9 | </TITLE> | |
10 | </HEAD> | |
11 | <BODY > | |
12 | <A HREF="main006.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
13 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
14 | <HR> | |
15 | ||
16 | <H2><A NAME="htoc33">7</A> Release notes</H2> | |
17 | Here are some caveats and open issues that apply to the current | |
18 | release.<BR> | |
19 | <BR> | |
20 | ||
21 | <H5>Deallocation of function results and <TT>out</TT> parameters:</H5> | |
22 | If a C function dynamically allocates some of its outputs (either | |
23 | returned or stored in <TT>out</TT> parameters), its IDL declaration must | |
24 | contain a <TT><FONT COLOR=blue>quote(dealloc,</FONT></TT> <TT><I><FONT COLOR=maroon>string</FONT></I></TT> <TT><FONT COLOR=blue>)</FONT></TT> clause to properly free the | |
25 | space occupied by those outputs after they have been converted to | |
26 | Caml. Otherwise, memory leaks will occur. (The only exception is | |
27 | results and output parameters of type <TT>[bigarray,managed] </TT><I>ty</I><TT>[]</TT>, | |
28 | where the Caml garbage collector takes care of deallocation.)<BR> | |
29 | <BR> | |
30 | This does not conform to the MIDL and COM specifications, which say | |
31 | that space for <TT>out</TT> data structures must be allocated | |
32 | with <TT>CoTaskMemAlloc</TT> by the callee, and automatically freed | |
33 | using <TT>CoTaskMemFree</TT> by the generated stub code. (The specs don't | |
34 | say what happens with the return value of the function.) | |
35 | However, there are many functions in Win32 (not to mention the | |
36 | Unix world) that do not follow this convention, and | |
37 | return data structures (e.g. strings) that are statically | |
38 | allocated, or require special deallocation functions. Hence, | |
39 | <TT>camlidl</TT> leaves deallocation of outputs entirely under user control.<BR> | |
40 | <BR> | |
41 | ||
42 | <H5>Allocation and deallocation of <TT>in,out</TT> parameters:</H5> | |
43 | For <TT>in,out</TT> parameters, the MIDL/COM rules are that the caller (the | |
44 | stub code) should allocate the inputs, the callee should free them | |
45 | and allocate again its outputs, and the caller should free the outputs. | |
46 | As explained above, <TT>camlidl</TT>-generated stubs don't automatically free | |
47 | the outputs. Worse, the inputs passed to the functions are allocated | |
48 | partially on the stack and partially in the heap | |
49 | (using <TT>CoTaskMemAlloc</TT>), so the callee may perform an incorrect | |
50 | free on a stack-allocated argument. The best thing to do is avoid | |
51 | <TT>in,out</TT> parameters entirely, and split them into one <TT>in</TT> and one | |
52 | <TT>out</TT> parameter.<BR> | |
53 | <BR> | |
54 | ||
55 | <H5>Reference-counting of COM interfaces:</H5> | |
56 | Caml finalized objects are used to call <TT>Release</TT> automatically on COM | |
57 | interfaces that become unreachable. The reference counting of | |
58 | interfaces passed as <TT>in</TT> and <TT>out</TT> parameters is correctly | |
59 | implemented. However, <TT>in,out</TT> parameters that are interfaces are not | |
60 | correctly handled. Again, avoid <TT>in,out</TT> parameters.<BR> | |
61 | <BR> | |
62 | ||
63 | <H5>COM support:</H5> | |
64 | The support for COM is currently quite small. COM components | |
65 | registered in the system registry can be imported via | |
66 | <TT>Com.create_instance</TT>. Components written in Caml can be exported as | |
67 | DLLs, but not yet as standalone servers. Preliminary support for | |
68 | dispatch interfaces is available, however many of the data types used | |
69 | in the Automation framework are not supported yet (e.g. <TT>SAFEARRAY</TT>). | |
70 | <BR> | |
71 | <BR> | |
72 | <HR> | |
73 | <A HREF="main006.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A> | |
74 | <A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A> | |
75 | </BODY> | |
76 | </HTML> |
Binary diff not shown
Binary diff not shown