Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > 'Dynamic' function calls

Reply
Thread Tools

'Dynamic' function calls

 
 
BartC
Guest
Posts: n/a
 
      12-21-2012
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

 
Reply With Quote
 
 
 
 
Anders Wegge Keller
Guest
Posts: n/a
 
      12-21-2012
"BartC" <(E-Mail Removed)> 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.*
 
Reply With Quote
 
 
 
 
BartC
Guest
Posts: n/a
 
      12-21-2012


"Anders Wegge Keller" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "BartC" <(E-Mail Removed)> 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

 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      12-21-2012
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
 
Reply With Quote
 
Rui Maciel
Guest
Posts: n/a
 
      12-21-2012
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
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      12-21-2012
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
 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      12-22-2012
Anders Wegge Keller <(E-Mail Removed)> wrote:
> "BartC" <(E-Mail Removed)> 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
 
Reply With Quote
 
BartC
Guest
Posts: n/a
 
      12-22-2012
"glen herrmannsfeldt" <(E-Mail Removed)> wrote in message
news:kb2ubm$4oj$(E-Mail Removed)...
> Anders Wegge Keller <(E-Mail Removed)> wrote:
>> "BartC" <(E-Mail Removed)> 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

 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      12-22-2012
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

 
Reply With Quote
 
glen herrmannsfeldt
Guest
Posts: n/a
 
      12-22-2012
Shao Miller <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
This function has an onClick event that calls a function that calls This function Bob Javascript 5 10-24-2006 04:11 PM
ods calls business object then method calls ta with output params andy6 ASP .Net 2 06-09-2006 01:54 AM
How override ALL function calls? (Is there a "function call function"?) seberino@spawar.navy.mil Python 2 08-01-2005 12:38 PM
MoVoIP - FREE MOBILE Inetrnet Phone Calls - FREE Internet Phone Calls ubifone VOIP 0 07-29-2005 04:31 PM
Sequence of constructor calls and destructor calls. Honne Gowda A C++ 2 10-31-2003 09:31 AM



Advertisments