Mercurial > pub > dyncall > dyncall
annotate dyncall/dyncall.3 @ 577:864cf3c3ceb9
mdoc tweak
author | Tassilo Philipp |
---|---|
date | Thu, 08 Sep 2022 15:31:44 +0200 |
parents | 53de6e16f445 |
children | 1d4f0f516483 |
rev | line source |
---|---|
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
1 .\" Copyright (c) 2007-2022 Daniel Adler <dadler AT uni-goettingen DOT de>, |
0 | 2 .\" Tassilo Philipp <tphilipp AT potion-studios DOT com> |
3 .\" | |
4 .\" Permission to use, copy, modify, and distribute this software for any | |
5 .\" purpose with or without fee is hereby granted, provided that the above | |
6 .\" copyright notice and this permission notice appear in all copies. | |
7 .\" | |
8 .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
9 .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
10 .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
11 .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
12 .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
13 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
14 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
15 .\" | |
16 .Dd $Mdocdate$ | |
17 .Dt dyncall 3 | |
18 .Sh NAME | |
19 .Nm dyncall | |
20 .Nd encapsulation of architecture-, OS- and compiler-specific function call | |
21 semantics | |
22 .Sh SYNOPSIS | |
23 .In dyncall.h | |
24 .Ft DCCallVM * | |
25 .Fn dcNewCallVM "DCsize size" | |
26 .Ft void | |
27 .Fn dcFree "DCCallVM * vm" | |
28 .Ft void | |
29 .Fn dcMode "DCCallVM * vm" "DCint mode" | |
30 .Ft void | |
31 .Fn dcReset "DCCallVM * vm" | |
32 .Ft void | |
33 .Fn dcArgBool "DCCallVM * vm" "DCbool arg" | |
34 .Ft void | |
35 .Fn dcArgChar "DCCallVM * vm" "DCchar arg" | |
36 .Ft void | |
37 .Fn dcArgShort "DCCallVM * vm" "DCshort arg" | |
38 .Ft void | |
39 .Fn dcArgInt "DCCallVM * vm" "DCint arg" | |
40 .Ft void | |
41 .Fn dcArgLong "DCCallVM * vm" "DClong arg" | |
42 .Ft void | |
43 .Fn dcArgLongLong "DCCallVM * vm" "DClonglong arg" | |
44 .Ft void | |
45 .Fn dcArgFloat "DCCallVM * vm" "DCfloat arg" | |
46 .Ft void | |
47 .Fn dcArgDouble "DCCallVM * vm" "DCdouble arg" | |
48 .Ft void | |
49 .Fn dcArgPointer "DCCallVM * vm" "DCpointer arg" | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
50 .Ft void |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
51 .Fn dcArgAggr "DCCallVM * vm" "const DCaggr * ag" "const void * value" |
0 | 52 .Ft DCvoid |
53 .Fn dcCallVoid "DCCallVM * vm" "DCpointer funcptr" | |
54 .Ft DCbool | |
55 .Fn dcCallBool "DCCallVM * vm" "DCpointer funcptr" | |
56 .Ft DCchar | |
57 .Fn dcCallChar "DCCallVM * vm" "DCpointer funcptr" | |
58 .Ft DCshort | |
59 .Fn dcCallShort "DCCallVM * vm" "DCpointer funcptr" | |
60 .Ft DCint | |
61 .Fn dcCallInt "DCCallVM * vm" "DCpointer funcptr" | |
62 .Ft DClong | |
63 .Fn dcCallLong "DCCallVM * vm" "DCpointer funcptr" | |
64 .Ft DClonglong | |
65 .Fn dcCallLongLong "DCCallVM * vm" "DCpointer funcptr" | |
66 .Ft DCfloat | |
67 .Fn dcCallFloat "DCCallVM * vm" "DCpointer funcptr" | |
68 .Ft DCdouble | |
69 .Fn dcCallDouble "DCCallVM * vm" "DCpointer funcptr" | |
70 .Ft DCpointer | |
71 .Fn dcCallPointer "DCCallVM * vm" "DCpointer funcptr" | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
72 .Ft DCpointer |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
73 .Fn dcCallAggr "DCCallVM * vm" "DCpointer funcptr" "const DCaggr * ag" "DCpointer ret" |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
74 .Ft void |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
75 .Fn dcBeginCallAggr "DCCallVM * vm" "const DCaggr * ag" |
0 | 76 .Ft void |
77 .Fn dcArgF "DCCallVM * vm" "const DCsigchar * signature" "..." | |
78 .Ft void | |
79 .Fn dcVArgF "DCCallVM * vm" "const DCsigchar * signature" "va_list args" | |
80 .Ft void | |
81 .Fn dcCallF "DCCallVM * vm" "DCValue * result" "DCpointer funcptr" "const DCsigchar * signature" "..." | |
82 .Ft void | |
83 .Fn dcVCallF "DCCallVM * vm" "DCValue * result" "DCpointer funcptr" "const DCsigchar * signature" "va_list args" | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
84 .Ft DCaggr* |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
85 .Fn dcNewAggr "DCsize maxFieldCount" "DCsize size" |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
86 .Ft void |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
87 .Fn dcAggrField "DCaggr* ag" "DCsigchar type" "DCint offset" "DCsize array_len" "..." |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
88 .Ft void |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
89 .Fn dcCloseAggr "DCaggr* ag" |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
90 .Ft void |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
91 .Fn dcFreeAggr "DCaggr* ag" |
0 | 92 .Sh DESCRIPTION |
93 The | |
94 .Nm | |
95 library encapsulates architecture-, OS- and compiler-specific function call | |
96 semantics in a virtual "bind argument parameters from left to right and then | |
97 call" interface allowing programmers to call C functions in a completely | |
98 dynamic manner. | |
99 .Pp | |
100 In other words, instead of calling a function directly, the | |
101 .Nm | |
102 library provides a mechanism to push the function parameters manually and to | |
103 issue the call afterwards. | |
104 .Pp | |
105 Since the idea behind this concept is similar to call dispatching mechanisms | |
106 of virtual machines, the object that can be dynamically loaded with arguments, | |
107 and then used to actually invoke the call, is called CallVM. It is possible to | |
108 change the calling convention used by the CallVM at run-time. Due to the fact | |
109 that nearly every platform comes with one or more distinct calling conventions, the | |
110 .Nm | |
111 library project intends to be a portable and open-source approach to the variety of | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
112 compiler/toolchain/platform-specific binary interfaces subtleties, and so on... |
0 | 113 .Pp |
114 .Fn dcNewCallVM | |
115 creates a new CallVM object, where | |
116 .Ar size | |
117 specifies the max size of the internal stack that will be allocated and used to | |
118 bind the arguments to. Use | |
119 .Fn dcFree | |
120 to destroy the CallVM object. | |
121 .Pp | |
122 .Fn dcMode | |
123 sets the calling convention to use. See dyncall.h for a list of | |
124 available modes. Note that some mode/platform combinations don't make any | |
125 sense (e.g. using a PowerPC calling convention on a MIPS platform) and are | |
126 silently ignored. | |
127 .Pp | |
128 .Fn dcReset | |
362
78dfa2f9783a
- added helper function dcGetModeFromCCSigChar() mapping callconv sig chars to respective mode
Tassilo Philipp
parents:
360
diff
changeset
|
129 resets the internal stack of arguments and prepares it for a new call. This |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
130 function should be called after setting the initial/main call mode (using |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
131 dcMode()), but prior to binding arguments to the CallVM (sometimes dcMode() |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
132 calls are needed after pushing some args, e.g. DC_SIGCHAR_CC_ELLIPSIS_VARARGS, |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
133 which is used prior to binding varargs of variadic functions). Use it also when |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
134 reusing a CallVM, as arguments don't get flushed automatically after a function |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
135 call invocation. Note: you should also call this function after initial |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
136 creation of the a CallVM object, as dcNewCallVM doesn't do this, implicitly. |
0 | 137 .Pp |
138 .Fn dcArgBool , | |
139 .Fn dcArgChar , | |
140 .Fn dcArgShort , | |
141 .Fn dcArgInt , | |
142 .Fn dcArgLong , | |
143 .Fn dcArgLongLong , | |
144 .Fn dcArgFloat , | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
145 .Fn dcArgDouble , |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
146 .Fn dcArgPointer |
0 | 147 and |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
148 .Fn dcArgAggr |
0 | 149 are used to bind arguments of the named types to the CallVM object. Arguments should |
150 be bound in | |
151 .Em "left to right" | |
152 order regarding the C function prototype. | |
153 .Pp | |
154 .Fn dcCallVoid , | |
155 .Fn dcCallBool , | |
156 .Fn dcCallChar , | |
157 .Fn dcCallShort , | |
158 .Fn dcCallInt , | |
159 .Fn dcCallLong , | |
160 .Fn dcCallLongLong , | |
161 .Fn dcCallFloat , | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
162 .Fn dcCallDouble , |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
163 .Fn dcCallPointer |
0 | 164 and |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
165 .Fn dcCallAggr |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
166 call the function with the previously bound arguments and return the named |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
167 type, where |
0 | 168 .Ar funcptr |
169 is a pointer to the function to call. After the invocation of the function | |
170 call, the argument values are still bound to the CallVM and a second call | |
171 using the same arguments can be issued. Call | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
172 .Fn dcReset |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
173 (as described above) to clear the internal argument stack. |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
174 .Pp |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
175 The interfaces for passing and/or returning aggregates (struct, union) by value |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
176 need to be explained as they are a bit more complex. Every such argument or |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
177 return type needs some extra info describing its layout via a |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
178 .Ft DCaggr |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
179 structure (except for non-trivial C++ aggregates, see AGGREGATE DESCRIPTION for |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
180 more information, below). Passing such arguments is then done by using |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
181 .Fn dcArgAggr , |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
182 where |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
183 .Ar ag |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
184 is a pointer to the description and |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
185 .Ar value |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
186 is a pointer to the aggregate in question. Calling a function that returns an |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
187 aggregate by value is done via two functions, |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
188 .Fn dcBeginCallAggr , |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
189 which handles special cases to facilitate the implementation and |
576 | 190 .Em must |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
191 be called |
576 | 192 .Em before |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
193 pushing any arguments, and finally |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
194 .Fn dcCallAggr |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
195 where |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
196 .Ar ag |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
197 is a pointer to the description (for both calls) and |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
198 .Ar ret |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
199 points to memory large enough to hold the to be returned aggregate. |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
200 .Fn dcCallAggr |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
201 returns a pointer to |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
202 .Ar ret . |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
203 .Pp |
576 | 204 .Em NOTE : |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
205 C++ non-trivial aggregates (check with the std::is_trivial type trait) need |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
206 some special handling. First of all, no aggregate description is needed and |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
207 NULL must be passed wherever a |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
208 .Ft DCaggr* |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
209 argument is needed. Also, as |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
210 .Nm |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
211 is oblivious to how to do any custom/non-trivial construction or copy, and thus |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
212 cannot do the copy of the aggregate, passed by-value, itself, the user has to |
559 | 213 provide such copies, manually, where needed (e.g. when passing such an |
214 aggregate as an argument by-value, using | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
215 .Fn dcArgAggr , |
559 | 216 in order to preserver the call's by-value semantics). |
0 | 217 .Pp |
218 .Fn dcArgF , | |
219 .Fn dcVArgF , | |
220 .Fn dcCallF | |
221 and | |
222 .Fn dcVCallF | |
223 can be used to bind arguments in a printf-style call, using a signature | |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
224 string encoding the argument and return types. The former 2 only bind |
0 | 225 the arguments to the |
226 .Ar vm | |
227 object (and ignore return types specified in the | |
228 signature), whereas the latter two issue a call to the given function pointer, | |
229 afterwards. The return value will be stored in | |
230 .Ar result . | |
360
32736025371f
- doc updates with more info about signature string usage
Tassilo Philipp
parents:
250
diff
changeset
|
231 The signature string also features calling convention mode selection. |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
232 For information about the signature format, refer to dyncall_signature.h or the |
0 | 233 .Nm |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
234 manual. |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
235 .Pp |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
236 For passing aggregates using |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
237 .Fn dc*F |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
238 functions, pass two varargs for each aggregate, first a pointer to DCaggr, then |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
239 a pointer to the aggregate in question. For returning aggregates using those |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
240 functions, pass |
576 | 241 .Em "two final extra" |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
242 arguments, first a pointer to DCaggr describing the return value, then a |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
243 pointer to memory large enough to hold it. An explicit call do |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
244 .Fn dcBeginCallAggr |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
245 is not needed in those cases, and a pointer to the to be returned aggregate is |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
246 returned via |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
247 .Ar result . |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
248 .Sh AGGREGATE DESCRIPTION |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
249 In order to describe an aggregate (except for C++ non-trivial aggregates, as |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
250 mentioned above), create a DCaggr object using |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
251 .Fn dcNewAggr , |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
252 where |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
253 .Ar maxFieldCount |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
254 is greater or equal to the number of fields the aggregate has (a nested |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
255 aggregate or an array is counted as one field), and |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
256 .Ar size |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
257 is the size of the aggregate (e.g. as determined by sizeof()). |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
258 .Pp |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
259 .Fn dcFreeAggr |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
260 destroys the DCaggr object. |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
261 .Pp |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
262 .Fn dcAggrField |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
263 is used to describe the aggregate, field-by-field (in order), with |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
264 .Ar type |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
265 being a DC_SIGCHAR_* (see dyncall_signature.h), |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
266 .Ar offset |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
267 being the offset of the field from the beginning of the aggregate (use C's |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
268 offsetof(3)), and |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
269 .Ar array_len |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
270 being the number of array elements, |
576 | 271 .Em iff |
533
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
272 the field is an array, otherwise use 1. For nested aggregates (when using |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
273 DC_SIGCHAR_AGGREGATE as |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
274 .Ft type ) , |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
275 one needs to pass the pointer to the nested aggregate's DCaggr object as last |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
276 argument (in |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
277 .Ar ... ) . |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
278 .Pp |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
279 Call |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
280 .Fn dcCloseAggr |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
281 after having described all fields of an aggregate. |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
282 .Pp |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
283 Note that c99 flexible array members do not count as a field, and must be |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
284 omitted, as passing aggregates with a flexible array member by value in C would |
71c884e610f0
- integration of patches from Raphael Luba, Thekla, Inc.:
Tassilo Philipp
parents:
362
diff
changeset
|
285 also omit it. |
575 | 286 .Sh EXAMPLES |
576 | 287 .Em Note : |
288 none of the examples below perform any error checking for simplicity of | |
575 | 289 the example. |
0 | 290 .Pp |
575 | 291 Let's start with a simple example, making a call to the function |
292 .Xr sqrt 3 . | |
0 | 293 Using the |
294 .Nm | |
295 library, this function would be called as follows: | |
296 .Bd -literal -offset indent | |
297 double r; | |
298 DCCallVM* vm = dcNewCallVM(4096); | |
299 dcMode(vm, DC_CALL_C_DEFAULT); | |
300 dcReset(vm); | |
575 | 301 /* call: double sqrt(double x); */ |
0 | 302 dcArgDouble(vm, 4.2373); |
303 r = dcCallDouble(vm, (DCpointer)&sqrt); | |
304 dcFree(vm); | |
305 .Ed | |
575 | 306 .Pp |
576 | 307 Note that the |
308 .Sy DCCallVM | |
309 object can be reused and shouldn't be created and freed per call, for | |
310 performance reasons. The following examples will omit creation and freeing of | |
311 the | |
312 .Sy DCCallVM , | |
313 for simplicity. | |
575 | 314 .Pp |
315 In a more complicated example, let's call | |
316 .Xr printf 3 , | |
317 which requires a different initial mode, as well as a mode switch for the | |
318 varargs part: | |
319 .Bd -literal -offset indent | |
576 | 320 int n_written_chars, r; |
321 /* initial callconv mode */ | |
575 | 322 dcMode(vm, DC_CALL_C_ELLIPSIS); |
323 dcReset(vm); | |
324 /* int printf(const char * restrict format, ...); */ | |
325 dcArgPointer(vm, "my printf(%d) %s string%n"); | |
576 | 326 /* switch mode for varargs part */ |
575 | 327 dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS); |
328 dcArgInt(vm, 3); | |
329 dcArgPointer(vm, "format"); | |
330 dcArgPointer(vm, &n_written_chars); | |
576 | 331 r = dcCallInt(vm, (DCpointer)&printf); |
332 .Ed | |
333 .Pp | |
334 .Ss C/trivial aggregates by-value | |
335 Onto an example passing an aggregate | |
336 .Em "by value" | |
337 (note that this is only available on platforms where macro | |
338 .Dv DC__Feature_AggrByVal | |
339 is defined). E.g. passing the following | |
340 .Sy struct S | |
341 to | |
342 .Fn f : | |
343 .Bd -literal -offset indent | |
344 struct S { char x[3]; double y; }; | |
345 void f(int, struct S); | |
575 | 346 .Ed |
347 .Pp | |
576 | 348 requires a |
349 .Sy DCaggr | |
350 description of the fields/layout of | |
351 .Sy struct S , | |
352 and is called as follows: | |
353 .Bd -literal -offset indent | |
354 struct S s = { { 56, -23, 0 }, -6.28 }; | |
355 | |
356 DCaggr *a = dcNewAggr(2, sizeof(struct S)); | |
357 dcAggrField(a, DC_SIGCHAR_CHAR, offsetof(struct S, x), 3); | |
358 dcAggrField(a, DC_SIGCHAR_DOUBLE, offsetof(struct S, y), 1); | |
359 dcCloseAggr(a); | |
360 | |
361 dcMode(vm, DC_CALL_C_DEFAULT); | |
362 dcArgInt(vm, 999); | |
363 dcArgAggr(vm, a, &s); | |
364 | |
365 dcCallVoid(vm, (DCpointer)&f); | |
366 | |
367 dcFreeAggr(a); | |
368 .Ed | |
369 .Pp | |
370 Let's look at an example returning | |
371 .Em "by value" | |
372 the above | |
373 .Sy struct S | |
374 from function: | |
375 .Bd -literal -offset indent | |
376 struct S g(int, short); | |
377 .Ed | |
378 .Pp | |
379 Omitting creation of the | |
577 | 380 .Sy DCaggr |
381 .Ar *a | |
576 | 382 description, for simplicity: |
383 .Bd -literal -offset indent | |
384 struct S s; | |
385 | |
386 dcMode(vm, DC_CALL_C_DEFAULT); | |
387 | |
388 /* needed when returning aggrs by value, *before* pushing args */ | |
389 dcBeginCallAggr(vm, a); | |
390 | |
391 dcArgInt(vm, 9); | |
392 dcArgShort(vm, 7); | |
393 | |
394 dcCallAggr(vm, (DCpointer)&g, a, &s); | |
395 .Ed | |
396 .Ss C++ | |
575 | 397 In our next example, let's look at calling a simple C++ method, with the method |
398 declaration being: | |
399 .Bd -literal -offset indent | |
400 virtual void Klass::Method(float, int); | |
401 .Ed | |
402 .Pp | |
576 | 403 To keep the example simple, let's assume we have a pointer to this virtual |
404 method in var | |
577 | 405 .Ar mptr |
576 | 406 (e.g. grabbed from the instance's vtable), and a pointer to the instance in var |
577 | 407 .Ar thisptr : |
575 | 408 .Bd -literal -offset indent |
409 /* thiscall calling convention */ | |
410 dcMode(vm, DC_CALL_C_DEFAULT_THIS); | |
411 dcReset(vm); | |
412 /* C++ methods use this-ptr as first/hidden argument */ | |
413 dcArgPointer(vm, thisptr); | |
414 dcArgFloat(vm, 2.3f); | |
415 dcArgInt(vm, -19); | |
416 dcCallVoid(vm, (DCpointer)mptr); | |
417 .Ed | |
418 .Pp | |
419 Extending the last example to a vararg method would need some more | |
420 .Xr dcMode 3 | |
421 calls. E.g.: | |
422 .Bd -literal -offset indent | |
423 virtual void Klass::Method(float, int, ...); | |
424 .Ed | |
425 .Pp | |
426 would be called as follows: | |
427 .Bd -literal -offset indent | |
428 /* thiscall calling convention (to pass this-ptr) */ | |
429 dcMode(vm, DC_CALL_C_DEFAULT_THIS); | |
430 dcReset(vm); | |
431 /* C++ methods use this-ptr as first/hidden argument */ | |
432 dcArgPointer(vm, thisptr); | |
433 /* fixed part of arguments */ | |
434 dcMode(vm, DC_CALL_C_ELLIPSIS); | |
435 dcArgFloat(vm, 2.3f); | |
436 dcArgInt(vm, -19); | |
437 /* variable part of arguments */ | |
438 dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS); | |
439 dcArgInt(vm, 7); | |
440 dcArgDouble(vm, 7.99); | |
441 dcCallVoid(vm, (DCpointer)mptr); | |
442 .Ed | |
443 .Pp | |
250
7cb8a0aaf638
- note about c99 (+ anon struct/union) requirements in doc
Tassilo Philipp
parents:
93
diff
changeset
|
444 .Sh CONFORMING TO |
7cb8a0aaf638
- note about c99 (+ anon struct/union) requirements in doc
Tassilo Philipp
parents:
93
diff
changeset
|
445 The dyncall library needs at least a c99 compiler with additional support for |
7cb8a0aaf638
- note about c99 (+ anon struct/union) requirements in doc
Tassilo Philipp
parents:
93
diff
changeset
|
446 anonymous structs/unions (which were introduced officially in c11). Given that |
7cb8a0aaf638
- note about c99 (+ anon struct/union) requirements in doc
Tassilo Philipp
parents:
93
diff
changeset
|
447 those are generally supported by pretty much all major c99 conforming compilers |
7cb8a0aaf638
- note about c99 (+ anon struct/union) requirements in doc
Tassilo Philipp
parents:
93
diff
changeset
|
448 (as default extension), it should build fine with a c99 toolchain. Strictly |
7cb8a0aaf638
- note about c99 (+ anon struct/union) requirements in doc
Tassilo Philipp
parents:
93
diff
changeset
|
449 speaking, dyncall conforms to c11, though. |
7cb8a0aaf638
- note about c99 (+ anon struct/union) requirements in doc
Tassilo Philipp
parents:
93
diff
changeset
|
450 .Ed |
0 | 451 .Sh SEE ALSO |
452 .Xr dyncallback 3 , | |
453 .Xr dynload 3 | |
454 and the | |
455 .Nm | |
93 | 456 manual (available in HTML and PDF format) for more information. |
0 | 457 .Sh AUTHORS |
458 .An "Daniel Adler" Aq dadler@uni-goettingen.de | |
459 .An "Tassilo Philipp" Aq tphilipp@potion-studios.com |