I am working on a project which uses C - Ada language binding. A function in C will call a function in Ada side. I want to make a variadic function in Ada which can receive a variable number of arguments sent from the C function. I also wanted to send different types of args at the same time like int, char, enums, etc at the same time. Is it possible to have this type of mechanism?
The forthcoming Ada standard Ada 202x is planning to provide support for calling C variadic functions.
You would then be able to write;
package C renames Interfaces.C;
procedure Printf (Format : in C.char_array)
with Import => True, Convention => C_Variadic_1, External_Name => "printf";
You cannot create a variadic function in Ada. You can simulate a variadic function is a couple of ways.
Ada allows you to specify default values for functions and procedures. One need not always specify the values of the default parameters if you want to use the default values.
You can define one or more of the parameters as a variant record.
It is not possible to call any C variadic function from Ada in a portable way!
One of the reason - some ABIs use special ways/registers to pass float values. This mean C compiler will use this registers, due to it's unknown in advance whether argument is float or not. Ada compiler will not use this registers (since you can't put float parameter in Ada wrapper function declaration). As result you will get crash, stack corruption or any other undefined behavior.
Particularly AMD64 ABI specifies:
%rax - with variable arguments passes information
about the number of vector registers used
%xmm0–%xmm1 - used to pass and return floating
point arguments
The only portable solution is using C wrapper with fixed number of parameters, then bind it as usual.
You can use 'address or the package System.Address_To_Access_Conversions and 'access (or 'unchecked_access) to generate addresses of each item you want to pass.
type Address_Array is array (positive range <>) of System.address;
function C_Caller(Params : Address_Array) return Integer is begin return 0; end;
X, Y, Z, Result : Integer;
begin
result := C_Caller(Address_Array'(x'address, y'address, z'address));
...then you'll need to pragma import the actual function.
Related
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 specifies (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.
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.
I am the author of libffi. It will do what you are asking.
#AnttiHaapala pointed out libffi. Here's some information about it:
What is libffi?
Some programs may not know at the time of compilation what arguments are to be passed to a function. For instance, an interpreter may be told at run-time about the number and types of arguments used to call a given function. ‘libffi’ can be used in such programs to provide a bridge from the interpreter program to compiled code.
The ‘libffi’ library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run time.
FFI stands for Foreign Function Interface. A foreign function interface is the popular name for the interface that allows code written in one language to call code written in another language. The ‘libffi’ library really only provides the lowest, machine dependent layer of a fully featured foreign function interface. A layer must exist above ‘libffi’ that handles type conversions for values passed between the two languages.
‘libffi’ assumes that you have a pointer to the function you wish to call and that you know the number and types of arguments to pass it, as well as the return type of the function.
Historic background
libffi, originally developed by Anthony Green (SO user: anthony-green), was inspired by the Gencall library from Silicon Graphics. Gencall was developed by Gianni Mariani, then employed by SGI, for the purpose of allowing calls to functions by address and creating a call frame for the particular calling convention. Anthony Green refined the idea and extended it to other architectures and calling conventions and open sourcing libffi.
Calling pow with libffi
#include <stdio.h>
#include <math.h>
#include <ffi.h>
int main()
{
ffi_cif call_interface;
ffi_type *ret_type;
ffi_type *arg_types[2];
/* pow signature */
ret_type = &ffi_type_double;
arg_types[0] = &ffi_type_double;
arg_types[1] = &ffi_type_double;
/* prepare pow function call interface */
if (ffi_prep_cif(&call_interface, FFI_DEFAULT_ABI, 2, ret_type, arg_types) == FFI_OK)
{
void *arg_values[2];
double x, y, z;
/* z stores the return */
z = 0;
/* arg_values elements point to actual arguments */
arg_values[0] = &x;
arg_values[1] = &y;
x = 2;
y = 3;
/* call pow */
ffi_call(&call_interface, FFI_FN(pow), &z, arg_values);
/* 2^3=8 */
printf("%.0f^%.0f=%.0f\n", x, y, z);
}
return 0;
}
I think I can assert libffi is a portable way to do what I asked, contrary to Antti Haapala's assertion that there isn't such a way. If we can't call libffi a portable technology, given how far it's ported/implemented across compilers and architectures, and which interface complies with C standard, we too can't call C, or anything, portable.
Information and history extracted from:
https://github.com/atgreen/libffi/blob/master/doc/libffi.info
http://en.wikipedia.org/wiki/Libffi
For safety you should unpack the variables before they are sent. Using assembler to hack the parameter stack might not be portable between compilers. Calling conventions might vary.
I can't speak for Ruby, but I have written quite a few programs using the C interfaces to Perl and Python. Perl and Python variables are not directly comparible with C variables, they have many more features. For example, a Perl scalar might have dual string and numeric values, only one of which is valid at any one time.
Conversion between Perl/Python variables and C is done using pack and unpack (in the struct module in Python). At the C interface you have to call specific APIs to do the conversion, depending on type. So, it is not just a straight pointer transfer, and it certainly does not involve assembler.
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 specifies (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.
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.
I am the author of libffi. It will do what you are asking.
#AnttiHaapala pointed out libffi. Here's some information about it:
What is libffi?
Some programs may not know at the time of compilation what arguments are to be passed to a function. For instance, an interpreter may be told at run-time about the number and types of arguments used to call a given function. ‘libffi’ can be used in such programs to provide a bridge from the interpreter program to compiled code.
The ‘libffi’ library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run time.
FFI stands for Foreign Function Interface. A foreign function interface is the popular name for the interface that allows code written in one language to call code written in another language. The ‘libffi’ library really only provides the lowest, machine dependent layer of a fully featured foreign function interface. A layer must exist above ‘libffi’ that handles type conversions for values passed between the two languages.
‘libffi’ assumes that you have a pointer to the function you wish to call and that you know the number and types of arguments to pass it, as well as the return type of the function.
Historic background
libffi, originally developed by Anthony Green (SO user: anthony-green), was inspired by the Gencall library from Silicon Graphics. Gencall was developed by Gianni Mariani, then employed by SGI, for the purpose of allowing calls to functions by address and creating a call frame for the particular calling convention. Anthony Green refined the idea and extended it to other architectures and calling conventions and open sourcing libffi.
Calling pow with libffi
#include <stdio.h>
#include <math.h>
#include <ffi.h>
int main()
{
ffi_cif call_interface;
ffi_type *ret_type;
ffi_type *arg_types[2];
/* pow signature */
ret_type = &ffi_type_double;
arg_types[0] = &ffi_type_double;
arg_types[1] = &ffi_type_double;
/* prepare pow function call interface */
if (ffi_prep_cif(&call_interface, FFI_DEFAULT_ABI, 2, ret_type, arg_types) == FFI_OK)
{
void *arg_values[2];
double x, y, z;
/* z stores the return */
z = 0;
/* arg_values elements point to actual arguments */
arg_values[0] = &x;
arg_values[1] = &y;
x = 2;
y = 3;
/* call pow */
ffi_call(&call_interface, FFI_FN(pow), &z, arg_values);
/* 2^3=8 */
printf("%.0f^%.0f=%.0f\n", x, y, z);
}
return 0;
}
I think I can assert libffi is a portable way to do what I asked, contrary to Antti Haapala's assertion that there isn't such a way. If we can't call libffi a portable technology, given how far it's ported/implemented across compilers and architectures, and which interface complies with C standard, we too can't call C, or anything, portable.
Information and history extracted from:
https://github.com/atgreen/libffi/blob/master/doc/libffi.info
http://en.wikipedia.org/wiki/Libffi
For safety you should unpack the variables before they are sent. Using assembler to hack the parameter stack might not be portable between compilers. Calling conventions might vary.
I can't speak for Ruby, but I have written quite a few programs using the C interfaces to Perl and Python. Perl and Python variables are not directly comparible with C variables, they have many more features. For example, a Perl scalar might have dual string and numeric values, only one of which is valid at any one time.
Conversion between Perl/Python variables and C is done using pack and unpack (in the struct module in Python). At the C interface you have to call specific APIs to do the conversion, depending on type. So, it is not just a straight pointer transfer, and it certainly does not involve assembler.
I'm trying to make some improvements to a interpreter for microcontrollers that I'm working on. For executing built-in functions I currently have something like this (albeit a bit faster):
function executeBuiltin(functionName, functionArgs) {
if (functionName=="foo") foo(getIntFromArg(functionArgs[0]));
if (functionName=="bar") bar(getIntFromArg(functionArgs[0]),getBoolFromArg(functionArgs[1]),getFloatFromArg(functionArgs[2]));
if (functionName=="baz") baz();
...
}
But it is for an embedded device (ARM) with very limited resources, and I need to cut down on the code size drastically. What I'd like to do is to have a general-purpose function for calling other functions with different arguments - something like this:
function executeBuiltin(functionName, functionArgs) {
functionData = fast_lookup(functionName);
call_with_args(functionData.functionPointer, functionData.functionArgumentTypes, functionArgs);
}
So I want to be able to call a standard C function and pass it whatever arguments it needs (which could all be of different types). For this, I need a call_with_args function.
I want to avoid re-writing every function to take argc+argv. Ideally each function that was called would be an entirely standard C function.
There's a discussion about this here - but has anything changed since 1993 when that post was written? Especially as I'm running on ARM where arguments are in registers rather than on the stack. Even if it's not in standard C, is there anything GCC specific that can be done?
UPDATE: It seems that despite behaviour being 'undefined' according to the spec, it looks like because of the way C calls work, you can pass more arguments to a function than it is expecting and everything will be fine, so you can unpack all the arguments into an array of uint32s, and can then just pass each uint32 to the function.
That makes writing 'nice' code for calls much easier, and it appears to work pretty well (on 32 bit platforms). The only problem seems to be when passing 64 bit numbers and compiling for 64bit x86 as it seems to do something particularly strange in that case.
Would it be possible to do at compile time with macros?
Something along the lines of:
https://www.redhat.com/archives/libvir-list/2014-March/msg00730.html
If runtime was required, perhaps __buildin_apply_args() could be leveraged.
from this document, section 5.5, Parameter Passing, it seems like parameters are passed both in registers and in stack, as with most of today platforms.
With "non standard C" I am thinking to pack the parameters and call the function following the documentation with some asm(). However you need a minimal information about the signature of the function being called anyway (I mean, how many bits for each argument to be passed).
From this point of view I would prefer to prepare an array of function names, an array of function pointers and an array of enumerated function signatures (in the number of bits of each argument... you don't need to differentiate void* from char* for example) and a switch/case on the signatures, and a switch/case on the last one. So I have reported two answers here.
You can do a very simple serialization to pass arbitrary arguments. Create an array and memcpy sizeof(arg) bytes into it for each passed argument.
Or you can create structs for function arguments.
Every function takes a char* or a void*. Then you pass either a pointer to a struct with that functions parameters, or you define a set of macros or functions to encode and decode arbitrary data from an array and pass the pointer to that array.
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 specifies (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.
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.
I am the author of libffi. It will do what you are asking.
#AnttiHaapala pointed out libffi. Here's some information about it:
What is libffi?
Some programs may not know at the time of compilation what arguments are to be passed to a function. For instance, an interpreter may be told at run-time about the number and types of arguments used to call a given function. ‘libffi’ can be used in such programs to provide a bridge from the interpreter program to compiled code.
The ‘libffi’ library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run time.
FFI stands for Foreign Function Interface. A foreign function interface is the popular name for the interface that allows code written in one language to call code written in another language. The ‘libffi’ library really only provides the lowest, machine dependent layer of a fully featured foreign function interface. A layer must exist above ‘libffi’ that handles type conversions for values passed between the two languages.
‘libffi’ assumes that you have a pointer to the function you wish to call and that you know the number and types of arguments to pass it, as well as the return type of the function.
Historic background
libffi, originally developed by Anthony Green (SO user: anthony-green), was inspired by the Gencall library from Silicon Graphics. Gencall was developed by Gianni Mariani, then employed by SGI, for the purpose of allowing calls to functions by address and creating a call frame for the particular calling convention. Anthony Green refined the idea and extended it to other architectures and calling conventions and open sourcing libffi.
Calling pow with libffi
#include <stdio.h>
#include <math.h>
#include <ffi.h>
int main()
{
ffi_cif call_interface;
ffi_type *ret_type;
ffi_type *arg_types[2];
/* pow signature */
ret_type = &ffi_type_double;
arg_types[0] = &ffi_type_double;
arg_types[1] = &ffi_type_double;
/* prepare pow function call interface */
if (ffi_prep_cif(&call_interface, FFI_DEFAULT_ABI, 2, ret_type, arg_types) == FFI_OK)
{
void *arg_values[2];
double x, y, z;
/* z stores the return */
z = 0;
/* arg_values elements point to actual arguments */
arg_values[0] = &x;
arg_values[1] = &y;
x = 2;
y = 3;
/* call pow */
ffi_call(&call_interface, FFI_FN(pow), &z, arg_values);
/* 2^3=8 */
printf("%.0f^%.0f=%.0f\n", x, y, z);
}
return 0;
}
I think I can assert libffi is a portable way to do what I asked, contrary to Antti Haapala's assertion that there isn't such a way. If we can't call libffi a portable technology, given how far it's ported/implemented across compilers and architectures, and which interface complies with C standard, we too can't call C, or anything, portable.
Information and history extracted from:
https://github.com/atgreen/libffi/blob/master/doc/libffi.info
http://en.wikipedia.org/wiki/Libffi
For safety you should unpack the variables before they are sent. Using assembler to hack the parameter stack might not be portable between compilers. Calling conventions might vary.
I can't speak for Ruby, but I have written quite a few programs using the C interfaces to Perl and Python. Perl and Python variables are not directly comparible with C variables, they have many more features. For example, a Perl scalar might have dual string and numeric values, only one of which is valid at any one time.
Conversion between Perl/Python variables and C is done using pack and unpack (in the struct module in Python). At the C interface you have to call specific APIs to do the conversion, depending on type. So, it is not just a straight pointer transfer, and it certainly does not involve assembler.
Using stdarg.h we can have function call with variable number of arguments. Is this also classified as function overloading?
Typically, function overloading has the implication that a different instance of a function/method is invoked depending on the given parameters. With variable arguments in C, the same function is called regardless of the parameter list. So based on that, the answer would be, "No." The function itself could of course mimic the behavior of overloading (do A if 1 argument, do B if 2 arguments, etc.), but it probably would not normally be termed "overloaded".
If you're referring to the implementation, no the compiler doesn't create overloads. Variable argument functions use va_start/va_arg/va_end to get their arguments.
Really, the answer could be "yes" or "no", depending on your definition of "function overloading".
From the compiler's perspective, there is only one function instantiated. From the user's persepctive, you could call this "overloading", but it's enforced by neither the language nor the compiler.
No.
Overloading means that a different function will be called depending on the number and/or type(s) of the arguments (some languages can also use the return type). But in this case, you're calling the same function regardless of the number of arguments.
It's no more overloading than func(42) vs. func(43).
Note that C99 does have something that behaves much like a narrow form of overloading. If you have #include <tgmath.h>, then sqrt(x) will call one of three different functions (sqrtf(), sqrt(), or sqrtl()), depending on the type of x. But that's actually a "type-generic macro", not an overloaded function. C11 adds the _Generic keyword, making this facility available to user-written code. But that's not related to the OP's question.
No, this is not an example of function overloading.
True overloading implies that you have several different functions with the same name, but distinguished by their argument lists. Depending on the arguments you pass, a different function instance will be invoked.
The answer is a straight no since C doesnt implement function overloading as is. It may allow you to alter an argument or two but internally what takes place isnt the actual mechanism of function overloading.
When an overloaded function is called, the C++ compiler selects the
proper function by examining the number, types and order of the
arguments in the call. Function overloading is commonly used to create
several functions of the same name that perform similar tasks but on
different data types.
I dont really understand your question but in general function overloading depends upon the difference in the arguments.
The arguments of the method.
public int add(int a, int b)
public float add(float a, float b)
This is function overloading. Atleast one of the arguments has to change for the function to be overloaded. This is not possible in early versions of c has they dont identify the functions by the types of parameters being passed.
Overloading means having several contracts tied to a same name.
For example:
int a(int i1, int i2);
int a(char c);
int a();
This doesn't exist in C as a symbol has to be unique within a same scope, but this exists in C++.
So even if it can be called several ways, with different parameters types and numbers, the function int a(int i, ...); cannot be seen as overloading in C as there is only one contract, which is "give me the arguments you wish and I'll find a way to handle them".
But this function can be seen as an overloading in C++ in such a case:
int a(int i, ...);
int a();