Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   'Dynamic' function calls (http://www.velocityreviews.com/forums/t955726-dynamic-function-calls.html)

BartC 12-21-2012 10:13 PM

'Dynamic' function calls
 
I have a requirement to call a function where:

o The function address is not known until runtime
o Neither are the number and type of the parameters
o Neither is the type of the function result
o (And neither is the calling convention, but it will likely be one of two)

So nothing too difficult... But I want to avoid sprawling code that tries to
enumerate all the possibilities.

(This to help an interpreted language call a foreign function in a
run-time-loaded dynamic library. It only needs to work on two platforms both
of which have a natural 32-bit int size)

The input parameters are easily dealt with, by letting all possibilities be
represented by an array of 0 to N 32-bit ints. N can be at least 12. But I
can't see any way in C of calling a function pointer with a variable number
of parameters, without writing at least N+1 different calls.

The function return type can be similarly limited to 4 possibilities: none,
32-bit, 64-bit, and 64-bit floating point (I think the latter uses a
different return register on the two platforms I have in mind). While the
call types will be C-language (I assume the library will use the same
convention as my C program), and whatever the OS might use.

So I can probably do this with only 13 x 4 x 2 lots of calls (about 100).
But if there's any way of simplifying this, without dropping into assembly
code, that would be appreciated!

--
Bartc


Anders Wegge Keller 12-21-2012 10:33 PM

Re: 'Dynamic' function calls
 
"BartC" <bc@freeuk.com> writes:

> The input parameters are easily dealt with, by letting all
> possibilities be represented by an array of 0 to N 32-bit ints. N
> can be at least 12. But I can't see any way in C of calling a
> function pointer with a variable number of parameters, without
> writing at least N+1 different calls.


What happens if you call a two-parameter function with (a1, a2, a3,
a4, a5, ...., aN) ?

We are way out of defined territory here, but most ABI's I know of,
would simply ignore the extra parameters. So you might be lucky that
your supported platforms' ABI would accept such an call.


--
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*

BartC 12-21-2012 10:58 PM

Re: 'Dynamic' function calls
 


"Anders Wegge Keller" <wegge@wegge.dk> wrote in message
news:87pq23hw6z.fsf@huddi.jernurt.dk...
> "BartC" <bc@freeuk.com> writes:
>
>> The input parameters are easily dealt with, by letting all
>> possibilities be represented by an array of 0 to N 32-bit ints. N
>> can be at least 12. But I can't see any way in C of calling a
>> function pointer with a variable number of parameters, without
>> writing at least N+1 different calls.

>
> What happens if you call a two-parameter function with (a1, a2, a3,
> a4, a5, ...., aN) ?
>
> We are way out of defined territory here, but most ABI's I know of,
> would simply ignore the extra parameters. So you might be lucky that
> your supported platforms' ABI would accept such an call.


I was wondering that, but didn't dare ask! On my main machine (Windows)
params are pushed right-to-left which helps. The other (Linux with gcc) I'll
have to check out, although I haven't even sorted the mysteries of dlopen()
yet..

Will need to do some tests I think. (I don't need to push 12 params every
time; either 4, 8 or 12 for example will reduce the code considerably).

--
Bartc


Ian Collins 12-21-2012 11:00 PM

Re: 'Dynamic' function calls
 
BartC wrote:
> I have a requirement to call a function where:
>
> o The function address is not known until runtime
> o Neither are the number and type of the parameters
> o Neither is the type of the function result
> o (And neither is the calling convention, but it will likely be one of two)
>
> So nothing too difficult... But I want to avoid sprawling code that tries to
> enumerate all the possibilities.


This isn't that unusual. The UNIX dlsym() returns all objects,
including function addresses as void*.

> (This to help an interpreted language call a foreign function in a
> run-time-loaded dynamic library. It only needs to work on two platforms both
> of which have a natural 32-bit int size)
>
> The input parameters are easily dealt with, by letting all possibilities be
> represented by an array of 0 to N 32-bit ints. N can be at least 12. But I
> can't see any way in C of calling a function pointer with a variable number
> of parameters, without writing at least N+1 different calls.


I have a library that uses dlsym() to find named functions in an XML-RPC
call. In my case, I do build an arrays of 0,1,2 and 3 parameter callers.

> The function return type can be similarly limited to 4 possibilities: none,
> 32-bit, 64-bit, and 64-bit floating point (I think the latter uses a
> different return register on the two platforms I have in mind). While the
> call types will be C-language (I assume the library will use the same
> convention as my C program), and whatever the OS might use.


In my case, I use seven return types used by XML-RPC, which does result
in quite a large matrix. The code (using C++ templates) is quite
compact, but takes a while to compile! This isn't usually a problem as
it just keeps one core busy while the rest of the library compiles on
the rest..

--
Ian Collins

Rui Maciel 12-21-2012 11:10 PM

Re: 'Dynamic' function calls
 
BartC wrote:

> I have a requirement to call a function where:
>
> o The function address is not known until runtime
> o Neither are the number and type of the parameters
> o Neither is the type of the function result
> o (And neither is the calling convention, but it will likely be one of
> two)
>
> So nothing too difficult... But I want to avoid sprawling code that tries
> to enumerate all the possibilities.
>
> (This to help an interpreted language call a foreign function in a
> run-time-loaded dynamic library. It only needs to work on two platforms
> both of which have a natural 32-bit int size)
>
> The input parameters are easily dealt with, by letting all possibilities
> be represented by an array of 0 to N 32-bit ints. N can be at least 12.
> But I can't see any way in C of calling a function pointer with a variable
> number of parameters, without writing at least N+1 different calls.
>
> The function return type can be similarly limited to 4 possibilities:
> none, 32-bit, 64-bit, and 64-bit floating point (I think the latter uses a
> different return register on the two platforms I have in mind). While the
> call types will be C-language (I assume the library will use the same
> convention as my C program), and whatever the OS might use.
>
> So I can probably do this with only 13 x 4 x 2 lots of calls (about 100).
> But if there's any way of simplifying this, without dropping into assembly
> code, that would be appreciated!


Is it possible to wrap that function? If that is possible then you could
solve the parameters issue by using a struct that stores a list of
parameters to pass an indeterminate number of parameters, and for the return
type you could use void pointer passed as a parameter and then let the
return value of the wrapper point which data type was passed, to be able to
cast that void pointer to something meaningful.

For example:

<pseudo-ish code>
struct Params {
int n;
int *parameters;
};

enum WrapperReturnType {
WRT_VOID,
WRT_FP32,
WRT_FP64
};

enum WrapperReturnType
wrapper(struct Params *parameters, void *returned_value);
</pseudo-ish code>


Rui Maciel

Shao Miller 12-21-2012 11:26 PM

Re: 'Dynamic' function calls
 
On 12/21/2012 17:13, BartC wrote:
> I have a requirement to call a function where:
>
> o The function address is not known until runtime
> o Neither are the number and type of the parameters
> o Neither is the type of the function result
> o (And neither is the calling convention, but it will likely be one of two)
>
> So nothing too difficult... But I want to avoid sprawling code that
> tries to
> enumerate all the possibilities.
>
> (This to help an interpreted language call a foreign function in a
> run-time-loaded dynamic library. It only needs to work on two platforms
> both
> of which have a natural 32-bit int size)
>
> The input parameters are easily dealt with, by letting all possibilities be
> represented by an array of 0 to N 32-bit ints. N can be at least 12. But I
> can't see any way in C of calling a function pointer with a variable number
> of parameters, without writing at least N+1 different calls.
>
> The function return type can be similarly limited to 4 possibilities: none,
> 32-bit, 64-bit, and 64-bit floating point (I think the latter uses a
> different return register on the two platforms I have in mind). While the
> call types will be C-language (I assume the library will use the same
> convention as my C program), and whatever the OS might use.
>
> So I can probably do this with only 13 x 4 x 2 lots of calls (about 100).
> But if there's any way of simplifying this, without dropping into assembly
> code, that would be appreciated!
>


It doesn't seem that portability is a concern, so perhaps you can
investigate the possibility of building an automatic VLA inside some
curly braces and then passing _no_ arguments, then see if the called
function picks up its arguments from the VLA in the caller. If it
works, it might reduce the combinations to 4 x 2.

(A VLA could even be one of 'unsigned char' and populated with the
object representations of "the parameters" the called function is
expecting, that way, all "params" needn't have the same size.)

I haven't used this strategy before on any platform, so please consider
that when considering the potential for wasting time. :)

- Shao Miller

glen herrmannsfeldt 12-22-2012 12:20 AM

Re: 'Dynamic' function calls
 
Anders Wegge Keller <wegge@wegge.dk> wrote:
> "BartC" <bc@freeuk.com> writes:


>> The input parameters are easily dealt with, by letting all
>> possibilities be represented by an array of 0 to N 32-bit ints. N
>> can be at least 12. But I can't see any way in C of calling a
>> function pointer with a variable number of parameters, without
>> writing at least N+1 different calls.


> What happens if you call a two-parameter function with (a1, a2, a3,
> a4, a5, ...., aN) ?


> We are way out of defined territory here, but most ABI's I know of,
> would simply ignore the extra parameters. So you might be lucky that
> your supported platforms' ABI would accept such an call.


For K&R C, that pretty much has to be true for varargs to work.

With ANSI C, at least C89, it only has to be true for actual
varargs routines. A completely different calling convention
could be used for non-varargs functions. But on most systems
the same convention is used.

The 8086 (and successors) have a RET (return) instruction that
can also pop a specified number of (16 bit) words off the stack.

The early 8086 compilers, for Fortran and Pascal, used this,
as they don't have any variable argument calls. That is, the
callee pops the arguments off the stack.

In the transition to 32 bit code, this evolved to the stdcall
( http://en.wikipedia.org/wiki/Stdcall#stdcall ) convention.

When C compilers started to appear for 8086, with the requirement
to support varargs (and before ANSI C), a new calling convention
was defined such that the caller (which knows the number of arguments)
pops them off the stack.

Along with the evolution (and naming) of stdcall, this evolved
to be named cdecl, where the caller pops the arguments.

Some compilers allow one to specify the calling convention with
the function prototype (or definition), such that they can be
mixed within a program.

For C functions that aren't varargs, it would be possible to use
the stdcall convention, though I don't know of any compilers that do.

With the cdecl convention, you should be safe passing extra arguments
that are ignored by the callee. The standard doesn't say anything
about this, though.

-- glen

BartC 12-22-2012 12:50 AM

Re: 'Dynamic' function calls
 
"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
news:kb2ubm$4oj$1@speranza.aioe.org...
> Anders Wegge Keller <wegge@wegge.dk> wrote:
>> "BartC" <bc@freeuk.com> writes:


>>> But I can't see any way in C of calling a
>>> function pointer with a variable number of parameters, without
>>> writing at least N+1 different calls.

>
>> What happens if you call a two-parameter function with (a1, a2, a3,
>> a4, a5, ...., aN) ?


> When C compilers started to appear for 8086, with the requirement
> to support varargs (and before ANSI C), a new calling convention
> was defined such that the caller (which knows the number of arguments)
> pops them off the stack.
>
> Along with the evolution (and naming) of stdcall, this evolved
> to be named cdecl, where the caller pops the arguments.
>
> Some compilers allow one to specify the calling convention with
> the function prototype (or definition), such that they can be
> mixed within a program.
>
> For C functions that aren't varargs, it would be possible to use
> the stdcall convention, though I don't know of any compilers that do.
>
> With the cdecl convention, you should be safe passing extra arguments
> that are ignored by the callee. The standard doesn't say anything
> about this, though.


That's a good point. On my machine, calls to normal C functions have the
stack adjusted by the caller. So the extra params are popped.

But with C calls to Win32 functions, for example, this is handled by the
callee, which will only pop what are expected. (And a test showed this
doesn't work. In any case, there is a further problem that the names of such
functions, when passed to the linker, have the number of parameter bytes
encoded into them! Circumventing that just caused a crash.)

--
Bartc


Shao Miller 12-22-2012 12:52 AM

Re: 'Dynamic' function calls
 
On 12/21/2012 19:20, glen herrmannsfeldt wrote:
>
> For C functions that aren't varargs, it would be possible to use
> the stdcall convention, though I don't know of any compilers that do.
>


stdcall is used pretty frequently in Microsoft-land. - Shao


glen herrmannsfeldt 12-22-2012 07:02 AM

Re: 'Dynamic' function calls
 
Shao Miller <sha0.miller@gmail.com> wrote:
> On 12/21/2012 19:20, glen herrmannsfeldt wrote:


>> For C functions that aren't varargs, it would be possible to use
>> the stdcall convention, though I don't know of any compilers that do.


> stdcall is used pretty frequently in Microsoft-land. - Shao


Yes, but are there C compilers that use stdcall without any special
attributes or compiler options requesting it?

Even more, that use it for libc?

I know it is common for Windows system calls, but then since it is
closed source we don't know that it is C.

-- glen


All times are GMT. The time now is 08:58 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57