Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
317 views
in Technique[技术] by (71.8m points)

assembly - In C, given a variable list of arguments, how to build a function call using them?

Suppose there's a list of arguments stored somehow, in a array for example.

Given a function pointer, how could I make a call to it passing the stored list of arguments?

I'm not trying to pass the array as an argument ok. You got it, ok? I want to pass each of its elements as an argument. An array is just to illustrate, I could be storing the arguments in some tuple structure. Also, look that I have at hand a function pointer and may have a signature in string format. I'm not trying to just define a function that is able to deal with a variadic list.

The only way I see how to do that is by employing assembly (by __asm push et al.) or this:

void (*f)(...);

int main()
{
    f = <some function pointer>;
    int args[]; <stored in a array, just to illustrate>
    int num_args = <some value>;

    switch(num_args)
    {
        case 0:
            f();
        break;

        case 1:
            f(args[0]);
        break;

        case 2:
            f(args[0], args[1]);
        break;

        /* etc */
    }

    return 0;
}

I don't like this approach too much...

Is there another portable and shorter form?

Several script languages are able to call C functions.

How script languages like Python or Ruby do that? How they implement it in a portable way? Does they just use assembly for several platforms or the above in the end?

Look that I'm really not asking about details of parameter marshaling and other stuff from script languages to C, I'm interested only in how, in the end, internally, the call to the C function by the script language is built.

EDIT

I'll keep the question's title but I think a better way for asking it is:

How to call a C function with its pointer and signature available only at runtime?

UPDATE

From Foreign Interface for PLT Scheme:

A call-out is a normal function call. In a dynamic setting, we create a “call-interface” object which speci?es (binary) input/output types; this object can be used with an arbitrary function pointer and an array of input values to perform a callout to the function and retrieve its result. Doing this requires manipulating the stack and knowing how a function is called, these are details that libffi deals with.

Thanks @AnttiHaapala for searching, finding and pointing libffi. It's what I was looking for, it's being used by a bunch of script languages, it's a portable library, implemented across several architectures and compilers.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You asked what is the portable way to call any function pointer with given number of arguments. The correct answer is that there is no such way.

For example python is able to call C functions through the ctypes module, but this is portable only for as long as you know the exact prototype and calling conventions. In C the easiest way to achieve the same is to know the prototype of the function pointer at compile time.

Update

For python / ctypes example, on each platform that has the ctypes module enabled, python knows how to write the calling stack for a given set of arguments. On Windows for example, python knows of 2 standard calling conventions - cdecl with C order of parameters on stack, and stdcall with "pascal style ordering". On Linux it does need to worry about whether to call 32 or 64 bit shared objects, and so forth. If python is compiled to another platform, the ctypes needs changes as well; the C code in ctypes module is not, as such, portable.

Update 2

For Python the magic is in here: ctypes source code. Notably it seems to link http://sourceware.org/libffi/ which might be just what you needed.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share

2.1m questions

2.1m answers

62 comments

56.6k users

...