comparison dyncall/dyncall.3 @ 575:e5164ef59a6a

- more examples in dyncall(3)
author Tassilo Philipp
date Thu, 08 Sep 2022 11:10:03 +0200
parents 52e87d4988e3
children 53de6e16f445
comparison
equal deleted inserted replaced
574:4cf57a9f8b92 575:e5164ef59a6a
281 after having described all fields of an aggregate. 281 after having described all fields of an aggregate.
282 .Pp 282 .Pp
283 Note that c99 flexible array members do not count as a field, and must be 283 Note that c99 flexible array members do not count as a field, and must be
284 omitted, as passing aggregates with a flexible array member by value in C would 284 omitted, as passing aggregates with a flexible array member by value in C would
285 also omit it. 285 also omit it.
286 .Sh EXAMPLE 286 .Sh EXAMPLES
287 Let's say, we want to make a call to the function: 287 Note: none of the examples below perform any error checking for simplicity of
288 .Bd -literal -offset indent 288 the example.
289 double sqrt(double x); 289 .Pp
290 .Ed 290 Let's start with a simple example, making a call to the function
291 .Pp 291 .Xr sqrt 3 .
292 Using the 292 Using the
293 .Nm 293 .Nm
294 library, this function would be called as follows: 294 library, this function would be called as follows:
295 .Bd -literal -offset indent 295 .Bd -literal -offset indent
296 double r; 296 double r;
297 DCCallVM* vm = dcNewCallVM(4096); 297 DCCallVM* vm = dcNewCallVM(4096);
298 dcMode(vm, DC_CALL_C_DEFAULT); 298 dcMode(vm, DC_CALL_C_DEFAULT);
299 dcReset(vm); 299 dcReset(vm);
300 /* call: double sqrt(double x); */
300 dcArgDouble(vm, 4.2373); 301 dcArgDouble(vm, 4.2373);
301 r = dcCallDouble(vm, (DCpointer)&sqrt); 302 r = dcCallDouble(vm, (DCpointer)&sqrt);
302 dcFree(vm); 303 dcFree(vm);
303 .Ed 304 .Ed
305 .Pp
306 Note that the DCCallVM object can be reused and shouldn't be created and freed
307 per call, for performance reasons. The following examples will omit creation
308 and freeing of the DCCallVM, for simplicity.
309 .Pp
310 In a more complicated example, let's call
311 .Xr printf 3 ,
312 which requires a different initial mode, as well as a mode switch for the
313 varargs part:
314 .Bd -literal -offset indent
315 int n_written_chars, n;
316 dcMode(vm, DC_CALL_C_ELLIPSIS);
317 dcReset(vm);
318 /* int printf(const char * restrict format, ...); */
319 dcArgPointer(vm, "my printf(%d) %s string%n");
320 dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS);
321 dcArgInt(vm, 3);
322 dcArgPointer(vm, "format");
323 dcArgPointer(vm, &n_written_chars);
324 n = dcCallInt(vm, (DCpointer)&printf);
325 .Ed
326 .Pp
327 In our next example, let's look at calling a simple C++ method, with the method
328 declaration being:
329 .Bd -literal -offset indent
330 virtual void Klass::Method(float, int);
331 .Ed
332 .Pp
333 To simplify this example let's assume we have a pointer to this virtual method
334 in var mptr (grabbed from the instance's vtable), and a pointer to the instance
335 in var thisptr:
336 .Bd -literal -offset indent
337 /* thiscall calling convention */
338 dcMode(vm, DC_CALL_C_DEFAULT_THIS);
339 dcReset(vm);
340 /* C++ methods use this-ptr as first/hidden argument */
341 dcArgPointer(vm, thisptr);
342 dcArgFloat(vm, 2.3f);
343 dcArgInt(vm, -19);
344 dcCallVoid(vm, (DCpointer)mptr);
345 .Ed
346 .Pp
347 Extending the last example to a vararg method would need some more
348 .Xr dcMode 3
349 calls. E.g.:
350 .Bd -literal -offset indent
351 virtual void Klass::Method(float, int, ...);
352 .Ed
353 .Pp
354 would be called as follows:
355 .Bd -literal -offset indent
356 /* thiscall calling convention (to pass this-ptr) */
357 dcMode(vm, DC_CALL_C_DEFAULT_THIS);
358 dcReset(vm);
359 /* C++ methods use this-ptr as first/hidden argument */
360 dcArgPointer(vm, thisptr);
361 /* fixed part of arguments */
362 dcMode(vm, DC_CALL_C_ELLIPSIS);
363 dcArgFloat(vm, 2.3f);
364 dcArgInt(vm, -19);
365 /* variable part of arguments */
366 dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS);
367 dcArgInt(vm, 7);
368 dcArgDouble(vm, 7.99);
369 dcCallVoid(vm, (DCpointer)mptr);
370 .Ed
371 .Pp
304 .Sh CONFORMING TO 372 .Sh CONFORMING TO
305 The dyncall library needs at least a c99 compiler with additional support for 373 The dyncall library needs at least a c99 compiler with additional support for
306 anonymous structs/unions (which were introduced officially in c11). Given that 374 anonymous structs/unions (which were introduced officially in c11). Given that
307 those are generally supported by pretty much all major c99 conforming compilers 375 those are generally supported by pretty much all major c99 conforming compilers
308 (as default extension), it should build fine with a c99 toolchain. Strictly 376 (as default extension), it should build fine with a c99 toolchain. Strictly