Mercurial > pub > dyncall > dyncall
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 |