Recent

Author Topic: Equivalent to stacking varargs  (Read 3845 times)

nanobit

  • Full Member
  • ***
  • Posts: 160
Re: Equivalent to stacking varargs
« Reply #15 on: April 17, 2021, 05:57:33 am »
Your solution looks very good. If you want to extend this later,
you could add a wrapper on top of your function pointer, conceptionally like:

procedure TPython.writeStdout( const format: string; const a: variant);
begin ... uniCall.run( FPySys_WriteStdout, format, a); end;

I see no easy uniCall Pascal-implementation, but it could
use some ffi-library (foreign function interface), like this:
https://dyncall.org/pub/dyncall/dyncall/file/default/test/ellipsis/main.cc
DC_CALL_C_ELLIPSIS for format-parameter, DC_CALL_C_ELLIPSIS_VARARGS for array

Thaddy

  • Hero Member
  • *****
  • Posts: 14204
  • Probably until I exterminate Putin.
Re: Equivalent to stacking varargs
« Reply #16 on: April 17, 2021, 08:48:46 am »
Note libffi already comes as standard package with the fpc distribution.
It is in packages/libffi.
The necessary binaries are in most linux distro's.
For windows the dll's are in both mingw and cygwin.
« Last Edit: April 17, 2021, 08:57:19 am by Thaddy »
Specialize a type, not a var.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Equivalent to stacking varargs
« Reply #17 on: April 17, 2021, 09:22:12 am »
@nanobit @Thaddy thanks, I'll check libffi presently.

The gist of the program I've written is that it takes a .inc file which is pretty much exactly what you'd use for static linkage, except that the last bit of each procedure/function declaration is replaced by a macro name. It generates two unit source files:

* A static unit which includes the .inc file expanding the macro.

* A dynamic unit which doesn't expand the macro, but declares an object with methods each of which is a thin wrapper around (a pointer to) an imported function (@nanobit, this is probably equivalent to what you've suggested). This also "automagically" generates all procedure/function types, fields of those types to hold function pointers, the implementation of each thin wrapper and so on, and as icing on the cake keeps comments in a format compatible with Lazarus hinting.

There's also provision for a file containing locally-written replacements for C/C++ macros.

The nice thing is that by naming the static unit and the dynamic object the same, the code at which imported functions are used is completely oblivious as to whether static or dynamic linkage is currently being used (except that dynamic vararg functions have to be imported explicitly, since wrappers can't be written).

The overall layout of the .inc file is something I hacked together quite some years ago, based on a Delphi interface somebody gave me which might have originated at NAG. But I also find that with care one can use the same file when *creating* a library, hence one can have common definitions (plus magic number protection etc.) when defining a frontend/backend architecture.

I've tacked on an example: the .inc files are created manually but the others by the program. The advantage doesn't really show for something this small, but by the time one has a dozen or so functions (e.g. for even a minimal ALSA interface https://github.com/MarkMLl/asound ) the work involved if it's done by hand is substantial. I'm not sure that the program is ready for "general release" yet, or who'd be interested, or whether I want to commit myself to unending maintenance as is apparently necessary for e.g. fpcupdeluxe.

MarkMLl
« Last Edit: April 17, 2021, 09:58:11 am by MarkMLl »
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

nanobit

  • Full Member
  • ***
  • Posts: 160
Re: Equivalent to stacking varargs
« Reply #18 on: April 17, 2021, 02:14:40 pm »
Oh, I've not seen libffi available, then some info in this example thread:
https://sourceware.org/pipermail/libffi-discuss/2021/002607.html

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Equivalent to stacking varargs
« Reply #19 on: April 17, 2021, 09:09:50 pm »
I'm left with the nagging feeling that because of the way that I'm generating code there's probably some obvious solution which I'm overlooking. Allowing the ease with which C code can crash if the format string is wrong I presume that the variadic parameters are pointers with no associated type information, but I think I really need to read up on this (e.g. via libffi).

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

jamie

  • Hero Member
  • *****
  • Posts: 6090
Re: Equivalent to stacking varargs
« Reply #20 on: April 18, 2021, 12:32:12 am »
I've been reading this thread and I still don't really know which direction  you are heading ?

are you trying to use a Lib function that expects specific C style variant parameters or are you trying to simulate the same in your code?


Anyways, Its most likely using the current style of  variant parameters
"..." in the last parameter of the function prototype...

 That style of calling is a pointer to a va_list which uses the va_start, va_arg and va_stop or end, I can't remember now, its been a while
but the those are just macros..

  Also for the C/C++ spec's you can get the record lay out of the current spec's.. I can't say if they are the same or not but if you are trying to simulate that to call an external function from fpc then I would think you need to create the third parameter as a pointer to an va_list

etc.
The only true wisdom is knowing you know nothing

nanobit

  • Full Member
  • ***
  • Posts: 160
Re: Equivalent to stacking varargs
« Reply #21 on: April 18, 2021, 08:12:47 am »
The thread is about calling external varargs routines, which is possible already,
but due to clientside technical reasons not most flexible.

1) Such library could allow: support fname( ..., format, variantArray),
where the user can create any (format, variantArray) pair at runtime.
Special case: If the c-api wants as format only a typelist (array signature),
then fname( ..., variantArray) would suffice, because the wrapper
can deduce the formatString from the array.

(Background: The formatString (between fixed args and var args) is function specific,
the c-api defines a relation between format and corresponding type,
for example 'i' could mean integer or Pinteger (if defined as returnvalue)).

2) Currently the array signature (types (thus count too)) has to be fixed
at compile time. This is minimal support, but mostly this can suffice.
But it's not pascal-ish and less than the library allows at runtime.
Also, the library user (because mostly he defines the signature) needs to interface the library directly,
because a generic wrapper (accepting an array) around the function pointer is not possible.
No wrapper also means no wrapper which could do parameter-validation (if wanted) or something else.

A ffi library is a wrapper which allows full use of the wrapped library.
« Last Edit: April 18, 2021, 09:20:34 am by nanobit »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Equivalent to stacking varargs
« Reply #22 on: April 18, 2021, 08:46:01 am »
1) Such library could allow: support doCall( ..., format, variantArray),
where the user can create any (format, variantArray) pair at runtime.
Special case: If the c-api wants as format only a typelist (array signature),
then doCall( ..., variantArray) would suffice, because the wrapper
can deduce the formatString from the array.

OTOH that would move away from the situation where I can at least call something that looks- in terms of parameter list)- exactly like what the C library documents :-/

What I'll do in the interim is make sure that there's some reliable way that a program can detect that it needs to initialise vararg imports as a special case, rather than its being done automatically.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

nanobit

  • Full Member
  • ***
  • Posts: 160
Re: Equivalent to stacking varargs
« Reply #23 on: April 18, 2021, 09:12:56 am »
Ah, "doCall" (now I have changed the post) was not chosen well in my text,
I meant specific functionnames, for example:
writeStdout( format, variantArray); in addition to:
PySys_WriteStdout( format, ....); // this is supported already
« Last Edit: April 18, 2021, 09:24:11 am by nanobit »

MarkMLl

  • Hero Member
  • *****
  • Posts: 6676
Re: Equivalent to stacking varargs
« Reply #24 on: April 18, 2021, 09:19:14 am »
Whatever... I'll investigate presently (but not right now :-)

Many thanks for the thoughts.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018