Mercurial > pub > dyncall > dyncall
comparison dyncall/dyncall.3 @ 579:1d4f0f516483
man pages:
- dyncall(3): removal of unnecessary whitespace
- dyncallback(3): added many more examples
author | Tassilo Philipp |
---|---|
date | Thu, 08 Sep 2022 17:36:20 +0200 |
parents | 864cf3c3ceb9 |
children |
comparison
equal
deleted
inserted
replaced
578:87b5f5d7af1f | 579:1d4f0f516483 |
---|---|
292 .Xr sqrt 3 . | 292 .Xr sqrt 3 . |
293 Using the | 293 Using the |
294 .Nm | 294 .Nm |
295 library, this function would be called as follows: | 295 library, this function would be called as follows: |
296 .Bd -literal -offset indent | 296 .Bd -literal -offset indent |
297 double r; | 297 double r; |
298 DCCallVM* vm = dcNewCallVM(4096); | 298 DCCallVM* vm = dcNewCallVM(4096); |
299 dcMode(vm, DC_CALL_C_DEFAULT); | 299 dcMode(vm, DC_CALL_C_DEFAULT); |
300 dcReset(vm); | 300 dcReset(vm); |
301 /* call: double sqrt(double x); */ | 301 /* call: double sqrt(double x); */ |
302 dcArgDouble(vm, 4.2373); | 302 dcArgDouble(vm, 4.2373); |
303 r = dcCallDouble(vm, (DCpointer)&sqrt); | 303 r = dcCallDouble(vm, (DCpointer)&sqrt); |
304 dcFree(vm); | 304 dcFree(vm); |
305 .Ed | 305 .Ed |
306 .Pp | 306 .Pp |
307 Note that the | 307 Note that the |
308 .Sy DCCallVM | 308 .Sy DCCallVM |
309 object can be reused and shouldn't be created and freed per call, for | 309 object can be reused and shouldn't be created and freed per call, for |
315 In a more complicated example, let's call | 315 In a more complicated example, let's call |
316 .Xr printf 3 , | 316 .Xr printf 3 , |
317 which requires a different initial mode, as well as a mode switch for the | 317 which requires a different initial mode, as well as a mode switch for the |
318 varargs part: | 318 varargs part: |
319 .Bd -literal -offset indent | 319 .Bd -literal -offset indent |
320 int n_written_chars, r; | 320 int n_written_chars, r; |
321 /* initial callconv mode */ | 321 /* initial callconv mode */ |
322 dcMode(vm, DC_CALL_C_ELLIPSIS); | 322 dcMode(vm, DC_CALL_C_ELLIPSIS); |
323 dcReset(vm); | 323 dcReset(vm); |
324 /* int printf(const char * restrict format, ...); */ | 324 /* int printf(const char * restrict format, ...); */ |
325 dcArgPointer(vm, "my printf(%d) %s string%n"); | 325 dcArgPointer(vm, "my printf(%d) %s string%n"); |
326 /* switch mode for varargs part */ | 326 /* switch mode for varargs part */ |
327 dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS); | 327 dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS); |
328 dcArgInt(vm, 3); | 328 dcArgInt(vm, 3); |
329 dcArgPointer(vm, "format"); | 329 dcArgPointer(vm, "format"); |
330 dcArgPointer(vm, &n_written_chars); | 330 dcArgPointer(vm, &n_written_chars); |
331 r = dcCallInt(vm, (DCpointer)&printf); | 331 r = dcCallInt(vm, (DCpointer)&printf); |
332 .Ed | 332 .Ed |
333 .Pp | 333 .Pp |
334 .Ss C/trivial aggregates by-value | 334 .Ss C/trivial aggregates by-value |
335 Onto an example passing an aggregate | 335 Onto an example passing an aggregate |
336 .Em "by value" | 336 .Em "by value" |
339 is defined). E.g. passing the following | 339 is defined). E.g. passing the following |
340 .Sy struct S | 340 .Sy struct S |
341 to | 341 to |
342 .Fn f : | 342 .Fn f : |
343 .Bd -literal -offset indent | 343 .Bd -literal -offset indent |
344 struct S { char x[3]; double y; }; | 344 struct S { char x[3]; double y; }; |
345 void f(int, struct S); | 345 void f(int, struct S); |
346 .Ed | 346 .Ed |
347 .Pp | 347 .Pp |
348 requires a | 348 requires a |
349 .Sy DCaggr | 349 .Sy DCaggr |
350 description of the fields/layout of | 350 description of the fields/layout of |
351 .Sy struct S , | 351 .Sy struct S , |
352 and is called as follows: | 352 and is called as follows: |
353 .Bd -literal -offset indent | 353 .Bd -literal -offset indent |
354 struct S s = { { 56, -23, 0 }, -6.28 }; | 354 struct S s = { { 56, -23, 0 }, -6.28 }; |
355 | 355 |
356 DCaggr *a = dcNewAggr(2, sizeof(struct S)); | 356 DCaggr *a = dcNewAggr(2, sizeof(struct S)); |
357 dcAggrField(a, DC_SIGCHAR_CHAR, offsetof(struct S, x), 3); | 357 dcAggrField(a, DC_SIGCHAR_CHAR, offsetof(struct S, x), 3); |
358 dcAggrField(a, DC_SIGCHAR_DOUBLE, offsetof(struct S, y), 1); | 358 dcAggrField(a, DC_SIGCHAR_DOUBLE, offsetof(struct S, y), 1); |
359 dcCloseAggr(a); | 359 dcCloseAggr(a); |
360 | 360 |
361 dcMode(vm, DC_CALL_C_DEFAULT); | 361 dcMode(vm, DC_CALL_C_DEFAULT); |
362 dcArgInt(vm, 999); | 362 dcArgInt(vm, 999); |
363 dcArgAggr(vm, a, &s); | 363 dcArgAggr(vm, a, &s); |
364 | 364 |
365 dcCallVoid(vm, (DCpointer)&f); | 365 dcCallVoid(vm, (DCpointer)&f); |
366 | 366 |
367 dcFreeAggr(a); | 367 dcFreeAggr(a); |
368 .Ed | 368 .Ed |
369 .Pp | 369 .Pp |
370 Let's look at an example returning | 370 Let's look at an example returning |
371 .Em "by value" | 371 .Em "by value" |
372 the above | 372 the above |
373 .Sy struct S | 373 .Sy struct S |
374 from function: | 374 from function: |
375 .Bd -literal -offset indent | 375 .Bd -literal -offset indent |
376 struct S g(int, short); | 376 struct S g(int, short); |
377 .Ed | 377 .Ed |
378 .Pp | 378 .Pp |
379 Omitting creation of the | 379 Omitting creation of the |
380 .Sy DCaggr | 380 .Sy DCaggr |
381 .Ar *a | 381 .Ar *a |
382 description, for simplicity: | 382 description, for simplicity: |
383 .Bd -literal -offset indent | 383 .Bd -literal -offset indent |
384 struct S s; | 384 struct S s; |
385 | 385 |
386 dcMode(vm, DC_CALL_C_DEFAULT); | 386 dcMode(vm, DC_CALL_C_DEFAULT); |
387 | 387 |
388 /* needed when returning aggrs by value, *before* pushing args */ | 388 /* needed when returning aggrs by value, *before* pushing args */ |
389 dcBeginCallAggr(vm, a); | 389 dcBeginCallAggr(vm, a); |
390 | 390 |
391 dcArgInt(vm, 9); | 391 dcArgInt(vm, 9); |
392 dcArgShort(vm, 7); | 392 dcArgShort(vm, 7); |
393 | 393 |
394 dcCallAggr(vm, (DCpointer)&g, a, &s); | 394 dcCallAggr(vm, (DCpointer)&g, a, &s); |
395 .Ed | 395 .Ed |
396 .Ss C++ | 396 .Ss C++ |
397 In our next example, let's look at calling a simple C++ method, with the method | 397 In our next example, let's look at calling a simple C++ method, with the method |
398 declaration being: | 398 declaration being: |
399 .Bd -literal -offset indent | 399 .Bd -literal -offset indent |
400 virtual void Klass::Method(float, int); | 400 virtual void Klass::Method(float, int); |
401 .Ed | 401 .Ed |
402 .Pp | 402 .Pp |
403 To keep the example simple, let's assume we have a pointer to this virtual | 403 To keep the example simple, let's assume we have a pointer to this virtual |
404 method in var | 404 method in var |
405 .Ar mptr | 405 .Ar mptr |
406 (e.g. grabbed from the instance's vtable), and a pointer to the instance in var | 406 (e.g. grabbed from the instance's vtable), and a pointer to the instance in var |
407 .Ar thisptr : | 407 .Ar thisptr : |
408 .Bd -literal -offset indent | 408 .Bd -literal -offset indent |
409 /* thiscall calling convention */ | 409 /* thiscall calling convention */ |
410 dcMode(vm, DC_CALL_C_DEFAULT_THIS); | 410 dcMode(vm, DC_CALL_C_DEFAULT_THIS); |
411 dcReset(vm); | 411 dcReset(vm); |
412 /* C++ methods use this-ptr as first/hidden argument */ | 412 /* C++ methods use this-ptr as first/hidden argument */ |
413 dcArgPointer(vm, thisptr); | 413 dcArgPointer(vm, thisptr); |
414 dcArgFloat(vm, 2.3f); | 414 dcArgFloat(vm, 2.3f); |
415 dcArgInt(vm, -19); | 415 dcArgInt(vm, -19); |
416 dcCallVoid(vm, (DCpointer)mptr); | 416 dcCallVoid(vm, (DCpointer)mptr); |
417 .Ed | 417 .Ed |
418 .Pp | 418 .Pp |
419 Extending the last example to a vararg method would need some more | 419 Extending the last example to a vararg method would need some more |
420 .Xr dcMode 3 | 420 .Xr dcMode 3 |
421 calls. E.g.: | 421 calls. E.g.: |
422 .Bd -literal -offset indent | 422 .Bd -literal -offset indent |
423 virtual void Klass::Method(float, int, ...); | 423 virtual void Klass::Method(float, int, ...); |
424 .Ed | 424 .Ed |
425 .Pp | 425 .Pp |
426 would be called as follows: | 426 would be called as follows: |
427 .Bd -literal -offset indent | 427 .Bd -literal -offset indent |
428 /* thiscall calling convention (to pass this-ptr) */ | 428 /* thiscall calling convention (to pass this-ptr) */ |
429 dcMode(vm, DC_CALL_C_DEFAULT_THIS); | 429 dcMode(vm, DC_CALL_C_DEFAULT_THIS); |
430 dcReset(vm); | 430 dcReset(vm); |
431 /* C++ methods use this-ptr as first/hidden argument */ | 431 /* C++ methods use this-ptr as first/hidden argument */ |
432 dcArgPointer(vm, thisptr); | 432 dcArgPointer(vm, thisptr); |
433 /* fixed part of arguments */ | 433 /* fixed part of arguments */ |
434 dcMode(vm, DC_CALL_C_ELLIPSIS); | 434 dcMode(vm, DC_CALL_C_ELLIPSIS); |
435 dcArgFloat(vm, 2.3f); | 435 dcArgFloat(vm, 2.3f); |
436 dcArgInt(vm, -19); | 436 dcArgInt(vm, -19); |
437 /* variable part of arguments */ | 437 /* variable part of arguments */ |
438 dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS); | 438 dcMode(vm, DC_CALL_C_ELLIPSIS_VARARGS); |
439 dcArgInt(vm, 7); | 439 dcArgInt(vm, 7); |
440 dcArgDouble(vm, 7.99); | 440 dcArgDouble(vm, 7.99); |
441 dcCallVoid(vm, (DCpointer)mptr); | 441 dcCallVoid(vm, (DCpointer)mptr); |
442 .Ed | 442 .Ed |
443 .Pp | 443 .Pp |
444 .Sh CONFORMING TO | 444 .Sh CONFORMING TO |
445 The dyncall library needs at least a c99 compiler with additional support for | 445 The dyncall library needs at least a c99 compiler with additional support for |
446 anonymous structs/unions (which were introduced officially in c11). Given that | 446 anonymous structs/unions (which were introduced officially in c11). Given that |