passing arguments dynamically to functions

J

Joel

Hi all,

Forgive me if I've expressed the subject line ill.

What I'm trying to do is to call a c++ function given the following:
a. A function name. This would be used to fetch a list of function
descriptors for the overloaded functions of that name. A function
descriptor would contain the address of the function to be called, and
a description of the parameters that it must take.
b. A list of parameters. This would be compared to the parameters in
each of the function descriptors to check which function must be
called, and then the desciptor would be given the parameters, and
requested to invoke that function

To illustrate:

...............................................
void SomeFunction (int a, int b)
{
// This is the function that must be invoked.
}

void GenericFunction (string FunctionName, ParameterCollection
Paremeters)
{
FunctionDescriptorList Descriptors;
Descriptors.LoadFunctionDescriptors (FunctionName);

// The Parameters object contains a list of parameters to be
passed.
// I would validate the parameters in the collection against the
// parameters required as specified by the DescriptorObject, and
use the
// DescriptorObject (which describes overloaded functions named
// SomeFunction) to call the matching SomeFunction, passing to it
// the two required integer parameters (as above).
}

...............................................

I am not sure how to achieve any of the invoking functionality I have
descibed in the comments above.

One approach I have tried is:

typedef void (* EllipsisFunction) (...);

void SomeFunction (int a, int b)
{
}

int main (void)
{
EllipsisFunction fn = (EllipsisFunction) SomeFunction;

fn (1, 2);

.....etc.
}

I could use code of this nature to effect something of what I am
trying to achieve (minus the validation), except for the fact that
again I must know the number of parameters that I call when I actually
type the code.

Another approach that I can use is that instead of SomeFunction taking
two integers, it could simply take a parameter collection object as
it's sole parameter. The second GenericFunction that I described above
would then have no problems in validating a ParameterCollection object
against the required parameters as described in a MethodDescriptor
object, and then in passing the ParameterCollection itself to
SomeFunction. This implies, however, that the signature of
SomeFunction would now have to take a ParameterCollection. Ideally, I
would prefer that if it means to take two integers, then the signature
should reflect that. I am aware tho that it isn't always an ideal
world ;)

But what I want to do is somehow to push the required parameters
(specified in a ParametersCollection object) onto the stack, before I
actually make the function call. Again, forgive me for using
non-technical words like "somehow". I have reached the extent of my
C++ knowledge in this particular area.

And that's where I am at present. It's a bit of a lengthy post but I
wanted to let you know how I've been thinking about this.

The problem is that I do not see right now a way to completely fulfill
the ideal that I have specified at the beginning of this post. Is
there a way that it could be accomplished?

With best regards,
cirquitz
 
J

JKop

What you want to do sound ludacris to me. How is your program going to know
how to work with each function it wants to call? Artificial Intelligence?
For instance, I myself can understand the following:

unsigned long CalculateCylinderCapacity(unsigned long height, unsigned long
radius);


But how the hell is the computer going to know how to work with that?


-JKop
 
J

Jeff Flinn

See boost::function and boost::bind at www.boost.org. This may help you to
better understand the intricacies involved in what you're trying to do.

Jeff F
 
B

Bob Hairgrove

On 29 Jun 2004 05:22:49 -0700, (e-mail address removed) (Joel) wrote:

[snip]
But what I want to do is somehow to push the required parameters
(specified in a ParametersCollection object) onto the stack, before I
actually make the function call. Again, forgive me for using
non-technical words like "somehow". I have reached the extent of my
C++ knowledge in this particular area.

And that's where I am at present. It's a bit of a lengthy post but I
wanted to let you know how I've been thinking about this.

The problem is that I do not see right now a way to completely fulfill
the ideal that I have specified at the beginning of this post. Is
there a way that it could be accomplished?

You cannot do this using only C++ ... by now, after all you have done,
I think you must realize this. However, if you don't mind mixing in a
bit of inline assembly code, you can set up the stack dynamically and
call the function. You have to be careful which calling convention is
used ... on Windows, there is __stdcall and __cdecl, for example. If
your called function is declared as __stdcall, the caller won't have
to clean up the stack after the function returns (otherwise: it does).
 
C

Chris Theis

[SNIP]
The problem is that I do not see right now a way to completely fulfill
the ideal that I have specified at the beginning of this post. Is
there a way that it could be accomplished?

With best regards,
cirquitz

You´re actually heading into the direction of generic functors implemented
with templates. I´m not gonna delve into the details here ´cause it would
become too long, so just check out:

http://www.codeproject.com/cpp/TTLFunction.asp

or the chapter about generic functors in "Modern Design C++" by Andrei
Alexandrescu.

HTH
Chris
 
R

Richard Herring

JKop <[email protected]> said:
What you want to do sound ludacris to me. How is your program going to know
how to work with each function it wants to call? Artificial Intelligence?
For instance, I myself can understand the following:

unsigned long CalculateCylinderCapacity(unsigned long height, unsigned long
radius);


But how the hell is the computer going to know how to work with that?

Well, clearly nobody's going to ask _you_ to design an interpreter for
their favourite language ;-)
 
R

Richard Herring

Bob Hairgrove said:
On 29 Jun 2004 05:22:49 -0700, (e-mail address removed) (Joel) wrote:

[snip]
But what I want to do is somehow to push the required parameters
(specified in a ParametersCollection object) onto the stack, before I
actually make the function call. Again, forgive me for using
non-technical words like "somehow". I have reached the extent of my
C++ knowledge in this particular area.

And that's where I am at present. It's a bit of a lengthy post but I
wanted to let you know how I've been thinking about this.

The problem is that I do not see right now a way to completely fulfill
the ideal that I have specified at the beginning of this post. Is
there a way that it could be accomplished?

You cannot do this using only C++ ... by now, after all you have done,
I think you must realize this.

You can achieve equivalent functionality.
However, if you don't mind mixing in a
bit of inline assembly code, you can set up the stack dynamically and
call the function. You have to be careful which calling convention is
used ... on Windows, there is __stdcall and __cdecl, for example. If
your called function is declared as __stdcall, the caller won't have
to clean up the stack after the function returns (otherwise: it does).

Eeurgh. As soon as you do that, it's way out of the realm of standard
C++ and therefore off topic.

But there's no reason why the "stack" on which his functions find their
arguments has to be the actual hardware stack, any more than those
"functions" have to be actual functions - they just need to be objects
which have some functional behaviour, and maybe also carry information
about the required parameters - in other words, function _objects_.
 
J

JKop

Richard Herring posted:
Well, clearly nobody's going to ask _you_ to design an interpreter for
their favourite language ;-)

Tough luck, I've already got a draft of the Standard.

-JKop
 
B

Bob Hairgrove

Bob Hairgrove said:
On 29 Jun 2004 05:22:49 -0700, (e-mail address removed) (Joel) wrote:

[snip]
But what I want to do is somehow to push the required parameters
(specified in a ParametersCollection object) onto the stack, before I
actually make the function call. Again, forgive me for using
non-technical words like "somehow". I have reached the extent of my
C++ knowledge in this particular area.

And that's where I am at present. It's a bit of a lengthy post but I
wanted to let you know how I've been thinking about this.

The problem is that I do not see right now a way to completely fulfill
the ideal that I have specified at the beginning of this post. Is
there a way that it could be accomplished?

You cannot do this using only C++ ... by now, after all you have done,
I think you must realize this.

You can achieve equivalent functionality.

Ahem ... we're waiting ... how do you do it in C++? (I'm not holding
my breath too long).
Eeurgh. As soon as you do that, it's way out of the realm of standard
C++ and therefore off topic.

His question was "how do I do this in C++"? Until you have shown us
otherwise, my answer is: you can't, because using only C++, the caller
must know at compile time how many arguments to pass and what type
they are. The *callee*, OTOH, can declare the function like this:

void SomeFunc(unsigned NumArgs, ...);

or even just (...) if there is some convention (i.e. a null argument
at the end) for knowing how many arguments to expect. The problem is
with the caller's code which does not know about the arguments at
compile time, but only at run time (if I understood the question
correctly, that is).

So what is better: to write one message saying: "You can't do this in
C++; it's off-topic to tell you how, so go f*** yourself", or: "You
can't do this in C++; but there is a way, and this is approximately
what you can do on at least one platform to achieve your goal."
But there's no reason why the "stack" on which his functions find their
arguments has to be the actual hardware stack, any more than those
"functions" have to be actual functions - they just need to be objects
which have some functional behaviour, and maybe also carry information
about the required parameters - in other words, function _objects_.

Oh yes, there are all those nice classes in <functional> like
std::bind2nd for wrapping multi-argument callback functions into one
function object. Still, the code using these has to know about the
arguments in advance, doesn't it?
 
J

Jerry Coffin

Hi all,

Forgive me if I've expressed the subject line ill.

What I'm trying to do is to call a c++ function given the following:
a. A function name. This would be used to fetch a list of function
descriptors for the overloaded functions of that name. A function
descriptor would contain the address of the function to be called, and
a description of the parameters that it must take.
b. A list of parameters. This would be compared to the parameters in
each of the function descriptors to check which function must be
called, and then the desciptor would be given the parameters, and
requested to invoke that function

[ and later implies this is for an interpreter ]

I've written a number of interpreters (and a few compilers) and
nothing like this has ever arisen.

In an interpreter, a function call in the source code does NOT result
in a call to the designated function as part of the interpreter.
Based on your discussion, I'm going to guess you're dealing with
either C++ or something fairly similar.

The interpreter normally maintains a stack (or more than one) on
behalf of the program being interpreted. When a function call is
encountered in the source code, this typically involves parsing the
parameters in the source code, finding the symbols in the symbol
table, and using their types to determine which of a number of
possible overloadings to invoke. Having done that, you'll carry out
any necessary type conversions on the operands, and then pushing the
resulting values (or addresses for pass-by-reference) onto the client
stack.

Havine done that, you typically invoke your interpreter function,
telling it what function in the client code is to be interpreted. One
common method for this is to give it the address of the symbol table
entry for the function being invoked.

It'll then walk through the code of that function, carrying out its
actions as needed (often including more recursive calls to interpret
functions invoked from that function).

Take note, however, that there is no overlap between the call stack of
the interpreter itself, and the call stack it maintains on behalf of
the client code. IOW, your basic idea of how to deal with a function
call seems to be mistaken.
 
R

Richard Herring

Bob Hairgrove said:
Bob Hairgrove said:
On 29 Jun 2004 05:22:49 -0700, (e-mail address removed) (Joel) wrote:

[snip]
But what I want to do is somehow to push the required parameters
(specified in a ParametersCollection object) onto the stack, before I
actually make the function call. Again, forgive me for using
non-technical words like "somehow". I have reached the extent of my
C++ knowledge in this particular area.

And that's where I am at present. It's a bit of a lengthy post but I
wanted to let you know how I've been thinking about this.

The problem is that I do not see right now a way to completely fulfill
the ideal that I have specified at the beginning of this post. Is
there a way that it could be accomplished?

You cannot do this using only C++ ... by now, after all you have done,
I think you must realize this.

You can achieve equivalent functionality.

Ahem ... we're waiting ... how do you do it in C++? (I'm not holding
my breath too long).

In effect, you write an interpreter. Functors within the interpreter
represent functions in the interpreted language.
His question was "how do I do this in C++"? Until you have shown us
otherwise, my answer is: you can't, because using only C++, the caller
must know at compile time how many arguments to pass and what type
they are. The *callee*, OTOH, can declare the function like this:

void SomeFunc(unsigned NumArgs, ...);

or even just (...) if there is some convention (i.e. a null argument
at the end) for knowing how many arguments to expect. The problem is
with the caller's code which does not know about the arguments at
compile time, but only at run time (if I understood the question
correctly, that is).

That's right, and the OP identified this problem. So you have a class
representing a collection of arguments, populate that accordingly and
pass it to the functor representing your function. There's a separate
functor class for each function to be implemented, and each of those
knows about the arguments of its corresponding function at compile time,
and can extract and validate the contents of the arguments object.
So what is better: to write one message saying: "You can't do this in
C++; it's off-topic to tell you how, so go f*** yourself", or: "You
can't do this in C++; but there is a way, and this is approximately
what you can do on at least one platform to achieve your goal."

Neither. The answer is "you _can_ do this in C++, but you need to think
a little more laterally."
Oh yes, there are all those nice classes in <functional> like
std::bind2nd for wrapping multi-argument callback functions into one
function object. Still, the code using these has to know about the
arguments in advance, doesn't it?
Indeed; those are for solving different problems.
 
J

Joel

Thanks a lot for all the ideas. My objective is to create C++ objects
that can describe their methods. I am not now interested much in
fields. It is method invocations that I would like to effect.

I had thought to use static C++ objects that would contain:
a. descriptive information, as well as
b. the address of the actual methods to be called. Each method
descriptor would have a method (such as "InvokeMethod") that would be
passed an object of the required type, and parameters required by the
method in question.

As it appears to me now:

1. I could place the responsibility on the C++ component developer, to
code a proxy function (such as "InvokeMethod") that accepts a method
name and a parameter stack from the interpreter, validates and
extracts the parameters as required, and calls the method specified by
the method name received. This code would be compiled into the
component. There would be no need for me to write framework code to
set up an appropriate stack. But it places a somewhat larger burden on
the component developer. This is effectively the approach of COM.

2. Alternatively, I write an "InvokeMethod" method to check up the
method descriptor, set up the stack (including a this pointer), and
pass control to the C++ objects method. This is a platform dependent
method. But it would place less of a burden on the component writer,
who would provide me with the mapping between names and method
addresses, and a description of parameters required by methods thus
exposed.

Whether or not I write an interpreter, as long as the component writer
is not responsible for actually translating a method name and an array
of parameters into a method call, it is up to my code to set up a
stack, pick up an address from a method descriptor as determined by
the name and parameter types/order, set up the appropriate stack, and
then invoke the method. At present, writing inline assembly code to
set up a stack appropriate to a method description, seems to best suit
the purpose. It would take the overloaded method resolution and
invocation out of the hands of the component developer, and enable
method invocation using C++ code, by specifying strings and a list of
parameters.

Best regards,
Joel.
 
J

Joel

Based on your discussion, I'm going to guess you're dealing with
either C++ or something fairly similar.
Yes, this is regarding C++.
In an interpreter, a function call in the source code does NOT result
in a call to the designated function as part of the interpreter.
This isn't meant to be an interpreter. The method name isn't picked up
from a piece of interpreted code. It is passed in a string to a
function (a little similar to what's done with the IDispatch interface
in ActiveX).
The interpreter normally maintains a stack (or more than one) on
behalf of the program being interpreted. When a function call is
encountered in the source code, this typically involves parsing the
parameters in the source code, finding the symbols in the symbol
table, and using their types to determine which of a number of
possible overloadings to invoke.
It seems to me that in the case of an interpreter, you can build your
own description of objects and methods, since you have to parse all
the code yourself. But since I am working with compiled C++
components, I would depend on the component to provide me with
information about itself.
Take note, however, that there is no overlap between the call stack of
the interpreter itself, and the call stack it maintains on behalf of
the client code.
I didn't mean to imply that the call stack of my proxy "InvokeMethod"
method would be the same one it passed over to the caller. In fact
that for what I have in mind, that would be impossible. The call stack
of "InvokeMethod" would contain an object pointer, a method name and
an array of parameters. It would have to build a stack, and call the
specified method appropriately.

With best regards,
Joel.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,175
Messages
2,570,942
Members
47,476
Latest member
blackwatermelon

Latest Threads

Top