I am writing a generic test function that will accept a function address (read from a map file) and arguments as comma separated data as arguments from a socket.
I am able to implement it for known function pointers.
like
void iif(int a, int b, float f);
typedef void (*fn_t)(int a, int b, float f);
With above approach I would write function pointers for all types of function implementation in the code base. Is there any generic way to do this?
No, since the compiler needs to know how to represent the arguments. It can't know that for a function pointer type that excludes the information, and thus it can't generate the call.
Functions with a small number of parameters might pass them in CPU registers, "spilling over" to the stack when many parameters are called for, for instance.
You can use varargs to come around this, doing so essentially "locks down" the way the arguments are passed. Of course, it forces the called functions to deal with varargs, which is not very convenient.
You can do the following.
fn_t fncptr;
fncptr= MapAddress + 0x(offset);
MapAdress is where you map file to memory address. (You can cast to DWORD before, if C++ compiler fails to add offset to void) Offset is where the function code in file. But rememder, you will need exetuce address to pointer in windows is PAGE_EXETUCE_READWRITE. ThenCall it like,
fncptr(arg1, arg2, arg3);
if compiler fails in first code, do this:
fn_t fncptr;
fncptr= (fn_t)((DWORD)MapAddress + 0x(offset));
Related
I am trying to write a program that will run a function from a dynamic library with its name, arguments and their types inputted by the user. I can get a void* pointer to this function using dlsym(func_name), however I do not know the types of arguments and their amount beforehand, so I can't dereference this pointer the normal way.
If I copy the byte representations of all the arguments into a char * array, can I call a function with this array as its arguments? For example when calling printf in assembly I can push the arguments and the format string to the stack and call printf. Maybe I can do something similar in C, or use assembly insertions?
For example, lets say the function is void func(int, double); and I am given arguments int a and double b. Then I would create an array:
char buf[sizeof(int) + sizeof(double)]
memcpy(buf, &a, sizeof(int))
memcpy(buf + sizeof(int), &b, sizeof(double))
And use it as the arguments pushed onto a stack.
The user inputs the name of the function, a string describing its type, and the arguments themselves. For example:
func_name
viid
5
6
2.34
func_name is the name of the function which will be used in dlsym. viid means that the function has void func_name(int, int, double) type (first char is the return type, the rest are arguments. v = void, i = int, d = double). The rest are arguments.
No, except possibly in ABIs that pass arguments purely on the stack. Any computing environment has a specification of how arguments are passed. (This specification is part of an Application Binary Interface [ABI] specification for the platform.) The argument types and sizes affect whether they are passed in general registers, floating-point registers, or other locations, as well as how they are aligned. Few, if any, such specifications pass arguments as a raw dump of bytes to the stack.
Code can be written to decode a description of the arguments and construct the necessary state to call the function. Such code would need to be written at least partially in assembly or various language extensions. (I would expect some people may have already written such code and made it available but do not have references for such.) This is likely an excessively costly solution to implement for most situations; you should seek alternative ways to achieve your underlying goal.
If an ABI does specify that all arguments are put on the stack, then it might be possible to pass arbitrary arguments in a structure containing an array of unsigned char:
A maximum size must be determined, such as struct { unsigned char bytes[128]; }, because standard C does not support structures of variable size.
The structure must be aligned as required for whatever argument has the strictest alignment.
The bytes of all arguments must be properly aligned within the structure.
The function would be called by passing the structure itself as an argument. Take care that the ABI must say that even large structures are passed directly on the stack. Some might say that a pointer to (a copy of) the structure is passed.
Note that ABIs might include other details affecting function calls, such as saying that a certain register must contain the number of arguments or be set a certain way, even if it does not itself contain an argument.
Is there a possibility to call function with variable arguments from the C code dynamically?
For example I have text file which contains data (written using this scheme: function_name arguments) for example:
func1 1 2 3
func2 1
func3
My program written in C is parsing this file and looks in a populated array (which holds function name in string and target native function pointer) for function with given name by comparing the string and calls a pointer of this function with arguments from the text file. For example functions like that:
void func1(int a, int b, int c) { }
void func2(int a, int b) { }
void func3() { }
The problem is that even if I know the number of arguments, I don't know how to write in C function pointer call with dynamic number of arguments. Is there a possibility to populate va_list (I know that this is NOT a container or a typical array!) then pass to the native function or any other way to do this? The only way which came into my mind is populating dynarec block with x86 code for calling native function with variable arguments, but it's not a clean solution. Is such thing even possible in plain C?
If it is hard to understand just write and I'll try to explain better. And if you want to write "use va_list" - then read carefully my post once again.
Thanks in advance.
I'm self answering, because this will be a solution for other people. If you want to call functions with variable arguments dynamically without writing direct machine code just use avcall library from FFCALL. Quick reference guide of avcall library can be found here. It's a crossplatform library that makes this possible. For example to call function named func1 with return type void which takes three arguments and all of them are of type int just do this:
#include <avcall.h>
int a = 1, b = 2, c = 3;
av_alist alist;
av_start_void(alist,&func1);
av_int(alist,a);
av_int(alist,b);
av_int(alist,c);
av_call(alist);
You can of course use this for functions which returns value or takes arguments of different type, for more just look at avcall library manual page. :)
I like your way of thinking, because obviously, you are a true hacker, but...
do not try to do it like this.
The proper way of doing this is to go alter these functions so that each one of them accepts an array of int instead of individual int parameters. But I suppose that if you had the freedom to change them, you would have done it already and you would not be asking.
The next best way of doing it is to write a number of functions, conv1(), conv2(), conv3() etc, each accepting an array of int, and a pointer to a function which accepts individual int parameters. So, convN() accepts an array of N integers, and a pointer to a function which accepts N individual int parameters. It reads each int from the array and passes it to the function as a parameter. It can do this, because it has been specifically written to work with a function of precisely that number of parameters. Then, in your table with function names and pointers to functions, add a pointer to the right convN() function, depending on the number of parameters that the target function expects.
Don't hack it.
So today I figured (for the first time admittedly) that int foo() is in fact different from int foo(void) in that the first one allows any number of inputs and the second one allows zero.
Does int foo() simply ignore any given inputs? If so, what's the point of allowing this form of function? If not, how can you access them and how is this different from having a variable argument list (e.g. something like int foo (int argc, ...))?
The key to understanding this is understanding the call stack. What happens when you call a function in C (with the standard x86 ABI — other platforms may vary) is that the caller pushes all of the arguments, in reverse order, onto the stack before calling the callee. Then, the callee can read as many of those arguments as it wants. If you use foo(void), obviously you won't read any. If you use foo(int), you'll be able to read one word into the stack below your current frame.
Using foo() (with no args specified) means that the compiler won't care to check the arguments you pass to foo. Anything goes; there's no contract. This can be useful if foo has two different implementations that take different types as arguments, and I want to be able to switch them out programmatically. (It's also sometimes useful when writing functions in assembler, where you can handle the stack and arguments yourself.) But remember that the compiler is not going to do any type-checking for you, so you have to be very careful.
This is different from foo(int, ...), since in that case, the function actually has a way to access all of the arguments (using varargs). There's no reason ever to actually define a function with foo(), since it's basically equivalent to foo(void). foo() is only useful for declarations.
First, take int foo(). This form is a function declaration that does not provide a prototype - that is, it doesn't specify the number and types of its arguments. It is an archaic form of function declaration - it's how functions were originally declared in pre-ANSI C. Such a function however does have a fixed number and type of arguments - it's just that the declaration doesn't tell the compiler what it is, so you are responsible for getting it right where you call the function. You declare such a function with arguments like so:
int foo(a, b)
int a;
char *b;
{
return a + strlen(b);
}
This form of function declaration is now obsolete.
int foo(void) is a modern declaration that provides a prototype; it declares a function that takes no arguments. int foo(int argc, ...) also provides a prototype; it declares a function that has one fixed integer argument and a variable argument list.
In standard conform C, you have to use int foo(void) if the function does not accept any parameters.
I guess it is compiler dependant what happens, when you pass arguments to a function with empty braces. But I don't think there is a way to access these parameters.
As for main, the only standard conform (pure c) ways to write them are either int main(void) or int main(int argc, char **argv) (or char *argv[] which is the same).
Well, in C++ the two forms are equivalent and they both declare a function that takes no arguments. If you try to call the function and pass in an argument, the compile will give an error.
On the other hand, C and Objective-C both treat the two forms differently. In these languages the first form declares a function that takes an unknown number of arguments, whereas the second form declares a function that takes no arguments at all. So, in C the following is valid code:
int foo() {
return 5;
}
int main() {
return foo(1, 2, 3);
}
The compiler doesn't complain, and the code runs fine (a C++ compiler would give an error on this same code).
Generally what you want in C and Objective-C is to use the second form and include the explicit void to indicate that the function should take no arguments. However, it's more common in C++ to use the first form because it's equivalent and shorter.
Is declaring an header file essential? This code:
main()
{
int i=100;
printf("%d\n",i);
}
seems to work, the output that I get is 100. Even without using stdio.h header file. How is this possible?
You don't have to include the header file. Its purpose is to let the compiler know all the information about stdio, but it's by no means necessary if your compiler is smart (or lazy).
You should include it because it's a good habit to get into - if you don't, then the compiler has no real way to know if you're breaking the rules, such as with:
int main (void) {
puts (7); // should be a string.
return 0;
}
which compiles without issue but rightly dumps core when running. Changing it to:
#include <stdio.h>
int main (void) {
puts (7);
return 0;
}
will result in the compiler warning you with something like:
qq.c:3: warning: passing argument 1 of ‘puts’ makes pointer
from integer without a cast
A decent compiler may warn you about this, such as gcc knowing about what printf is supposed to look like, even without the header:
qq.c:7: warning: incompatible implicit declaration of
built-in function ‘printf’
How is this possible? In short: three pieces of luck.
This is possible because some compilers will make assumptions about undeclared functions. Specifically, parameters are assumed to be int, and the return type also int. Since an int is often the same size as a char* (depending on the architecture), you can get away with passing ints and strings, as the correct size parameter will get pushed onto the stack.
In your example, since printf was not declared, it was assumed to take two int parameters, and you passed a char* and an int which is "compatible" in terms of the invocation. So the compiler shrugged and generated some code that should have been about right. (It really should have warned you about an undeclared function.)
So the first piece of luck was that the compiler's assumption was compatible with the real function.
Then at the linker stage, because printf is part of the C Standard Library, the compiler/linker will automatically include this in the link stage. Since the printf symbol was indeed in the C stdlib, the linker resolved the symbol and all was well. The linking was the second piece of luck, as a function anywhere other than the standard library will need its library linked in also.
Finally, at runtime we see your third piece of luck. The compiler made a blind assumption, the symbol happened to be linked in by default. But - at runtime you could have easily passed data in such a way as to crash your app. Fortunately the parameters matched up, and the right thing ended up occurring. This will certainly not always be the case, and I daresay the above would have probably failed on a 64-bit system.
So - to answer the original question, it really is essential to include header files, because if it works, it is only through blind luck!
As paxidiablo said its not necessary but this is only true for functions and variables but if your header file provides some types or macros (#define) that you use then you must include the header file to use them because they are needed before linking happens i.e during pre-processing or compiling
This is possible because when C compiler sees an undeclared function call (printf() in your case) it assumes that it has
int printf(...)
signature and tries to call it casting all the arguments to int type. Since "int" and "void *" types often have same size it works most of the time. But it is not wise to rely on such behavior.
C supprots three types of function argument forms:
Known fixed arguments: this is when you declare function with arguments: foo(int x, double y).
Unknown fixed arguments: this is when you declare it with empty parentheses: foo() (not be confused with foo(void): it is the first form without arguments), or not declare it at all.
Variable arguments: this is when you declare it with ellipsis: foo(int x, ...).
When you see standard function working then function definition (which is in form 1 or 3) is compatible with form 2 (using same calling convention). Many old std. library functions are so (as desugned to be), because they are there form early versions of C, where was no function declarations and they all was in form 2. Other function may be unintentionally be compatible with form 2, if they have arguments as declared in argument promotion rules for this form. But some may not be so.
But form 2 need programmer to pass arguments of same types everywhere, because compiler not able to check arguments with prototype and have to determine calling convention osing actual passed arguments.
For example, on MC68000 machine first two integer arguments for fixed arg functions (for both forms 1 and 2) will be passed in registers D0 and D1, first two pointers in A0 and A1, all others passed through stack. So, for example function fwrite(const void * ptr, size_t size, size_t count, FILE * stream); will get arguments as: ptr in A0, size in D0, count in D1 and stream in A1 (and return a result in D0). When you included stdio.h it will be so whatever you pass to it.
When you do not include stdio.h another thing happens. As you call fwrite with fwrite(data, sizeof(*data), 5, myfile) compiler looks on argruments and see that function is called as fwrite(*, int, int, *). So what it do? It pass first pointer in A0, first int in D0, second int in D1 and second pointer in A1, so it what we need.
But when you try to call it as fwrite(data, sizeof(*data), 5.0, myfile), with count is of double type, compiler will try to pass count through stack, as it is not integer. But function require is in D1. Shit happens: D1 contain some garbage and not count, so further behaviour is unpredictable. But than you use prototype defined in stdio.h all will be ok: compiler automatically convert this argument to int and pass it as needed. It is not abstract example as double in arument may be just result of computation involving floating point numbers and you may just miss this assuming result is int.
Another example is variable argument function (form 3) like printf(char *fmt, ...). For it calling convention require last named argument (fmt here) to be passed through stack regardess of its type. So, then you call printf("%d", 10) it will put pointer to "%d" and number 10 on stack and call function as need.
But when you do not include stdio.h comiler will not know that printf is vararg function and will suppose that printf("%d", 10) is calling to function with fixed arguments of type pointer and int. So MC68000 will place pointer to A0 and int to D0 instead of stack and result is again unpredictable.
There may be luck that arguments was previously on stack and occasionally read there and you get correct result... this time... but another time is will fail. Another luck is that compiler takes care if not declared function may be vararg (and somehow makes call compatible with both forms). Or all arguments in all forms are just passed through stack on your machine, so fixed, unknown and vararg forms are just called identically.
So: do not do this even you feel lucky and it works. Unknown fixed argument form is there just for compatibility with old code and is strictly discouraged to use.
Also note: C++ will not allow this at all, as it require function to be declared with known arguments.
I came across the following function signature and I wondered if this (the ellipsis, or "...") is some kind of polymorphism?
#include <fcntl.h>
int fcntl(int fd, int cmd, ... );
Thanks in advance.
It's a variable argument list.
That is a variadic function. See stdarg.h for more details.
The ... means that you can pass any number of arguments to this function, as other commenters have already mentioned. Since the optional arguments are not typed, the compiler cannot check the types and you can technically pass in any argument of any type.
So does this mean you can use this to implement some kind of polymorphic function? (I.e., a function that performs some operation based on the type of its arguments.)
No.
The reason you cannot do this, is because you cannot at runtime inspect the types of the arguments passed in. The function reading in the variable argument list is expected to already know the types of the optional arguments it is going to receive.
In case of a function that really is supposed to be able to take any number of arguments of any type (i.e., printf), the types of the arguments are passed in via the format string. This means that the caller has to specify the types it is going to pass in at every invocation, removing the benefit of polymorphic functions (that the caller doesn't have to know the types either).
Compare:
// Ideal invocation
x = multiply(number_a, number_b)
y = multiply(matrix_a, matrix_b)
// Standard C invocation
x = multiply_number(number_a, number_b)
y = multiply_matrix(matrix_a, matrix_b)
// Simulated "polymorphism" with varargs
x = multiply(T_NUMBER, number_a, number_b)
y = multiply(T_MATRIX, matrix_a, matrix_b)
You have to specify the type before the varargs function can do the right thing, so this gains you nothing.
No, that's the "ellipsis" you're seeing there, assuming you're referring to the ... part of the declaration.
Basically it says that this function takes an unknown number of arguments after the first two that are specified there.
The function has to be written in such a way that it knows what to expect, otherwise strange results will ensue.
For other functions that support this, look at the printf function and its variants.
Does C support polymorphism?
No, it doesn't.
However there are several libraries, such as Python C API, that implements a rough variant of polymorphism using structs and pointers. Beware that compiler cannot perform appropriate type checking in most cases.
The tecnhique is simple:
typedef struct {
char * (*to_string)();
} Type;
#define OBJ_HEADER Type *ob_type
typedef struct {
OBJ_HEADER;
} Object;
typedef struct {
OBJ_HEADER;
long ival;
} Integer;
typedef struct {
OBJ_HEADER;
char *name;
char *surname;
} Person;
Integer and Person get a Type object with appropriate function pointers (e.g. to functions like integer_to_string and person_to_string).
Now just declare a function accepting an Object *:
void print(Object *obj) {
printf("%s", obj->type->to_string());
}
now you can call this function with both an Integer and a Person:
Integer *i = make_int(10);
print((Object *) i);
Person *p = make_person("dfa");
print((Object *) p);
EDIT
alternatively you can declare i and p as Object *; of course make_int and make_person will allocate space for Integer and Person and do the appropriate cast:
Object *
make_integer(long i) {
Integer *ob = malloc(sizeof(Integer));
ob->ob_type = &integer_type;
ob->ival = i;
return (Object *) ob;
}
NB: I cannot compile these examples rigth now, please doublecheck them.
I came across the following function signature and I wondered if this (the ellipsis, or "...") is some kind of polymorphism?
yes, it is a primitive form of polymorphism. With only one function signature you are able to pass various structures. However the compiler cannot help you with detecting type errors.
Adding to what's been said: C supports polymorphism through other means. For example, take the standard library qsort function which sorts data of arbitrary type.
It is able to do so by means of untyped (void) pointers to the data. It also needs to know the size of the data to sort (provided via sizeof) and the logic that compares the objects' order. This is accomplished by passing a function pointer to the qsort function.
This is a prime example of runtime polymorphism.
There are other ways to implement object-oriented behaviour (in particular, virtual function calls) by managing the virtual function tables manually. This can be done by storing function pointers in structures and passing them around. Many APIs do so, e.g. the WinAPI, which even uses advanced aspects of object orientation, e.g. base class call dispatch (DefWindowProc, to simulate calling the virtual method of the base class).
I assume you are referring to the ellipsis (...)? If so this indicates that 0 or more parameters will follow. It is called varargs, defined in stdarg.h
http://msdn.microsoft.com/en-us/library/kb57fad8.aspx
printf uses this functionality. Without it you wouldn't be able to keep adding parameters to the end of the function.
C supports a crude form of Polymorphism. I.e. a type being able to appear and behave as another type. It works in a similar was as in C++ under the hood (relying on memory being aligned) but you have to help the compiler out by casting. E.g. you can define a struct:
typedef struct {
char forename[20];
char surname[20];
} Person;
And then another struct:
typedef struct {
char forename[20];
char surname[20];
float salary;
char managername[20];
} Employee;
Then
int main (int argc, int *argv)
{
Employee Ben;
setpersonname((Person *) &Ben);
}
void setpersonname(Person *person)
{
strcpy(person->forename,"Ben");
}
The above example shows Employee being used as a Person.
No, it is a function that is taking variable number of arguments.
That is not technically polymorphism. fcntl takes variable number of arguments & that is the reason for the ... similar to printf function.
C neither supports function overloading - which is a type of ad-hoc polymorphism based on compile-time types - nor multiple dispatch (ie overloading based on runtime types).
To simulate function overloading in C, you have to create multiple differently named functions. The functions' names often contain the type information, eg fputc() for characters and fputs() for strings.
Multiple dispatch can be implemented by using variadic macros. Again, it's the programmer's job to provide the type information, but this time via an extra argument, which will be evaluated at runtime - in contrast to the compile-time function name in case of the approach given above. The printf() family of functions might not be the best example for multiple dispatch, but I can't think of a better one right now.
Other approaches to multiple dispatch using pointers instead of variadic functions or wrapping values in structures to provide type annotations exist.
The printf declaration in the standard library is
int printf(const char*, ...);
Think about that.
You can write code that supports Polymorphic behavior in C, but the ... (ellipsis) is not going to be much help. That is for variable arguments to a function.
If you want polymorphic behavior you can use, unions and structures to construct a data structure that has a "type" section and variable fields depending on type. You can also include tables of function pointers in the structures. Poof! You've invented C++.
Yes C Do support the polymorphism
the Code which we write in the C++ using virtual to implement the polymorphism
if first converted to a C code by Compiler (one can find details here).
It's well known that virtual functionality in C++ is implemented using function pointers.