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