Pass a string containing a function name and its arguments to another function. - c

I would like to pass a string to a function in C in which the function will parse out a function name, the arguments for the function, and its datatypes, and then call the function for me. What is the best approach?

If you want to write a function with a format string and variable arguments like:
int function(const char* strFormat, ... )
{
//parse out the format using regex or something
//then store the data into the variable aruments
//or create a string concatenating everything
}
like, say printf, sprintf, or scanf does,
then the best thing for you to do is look at some good tutorials.
http://msdn.microsoft.com/en-us/library/fxhdxye9(v=vs.80).aspx
http://www.cprogramming.com/tutorial/c/lesson17.html
If you are wanting to actually pass a function name for the function to call, along with its arguments, you either need to implement some form of reflection or introspection in your c code, a really complex switch statement which calls the functions for you based upon the string value, or write some complex macros to act as a sort of a secondary
compiler.
glib's gobject is an excellent example of introspection in c.
http://developer.gnome.org/gobject/stable/
something simple without introspection may be:
void* function (const char* strFunctionName, ... )
{
if(!strcmp(strFunctionName, "functionA"))
{
//use va_list to parse out the arguments for the function.
functionA(//each of the arguments from va_list);
}
else if(!strcmp(strFunctionName, "functionB"))
{
//use va_list to parse out the arguments for the function.
functionB(//args from va_list);
}
...
}
If you have something more specific in mind, please specify in your question.

I'm not sure if this is standard, but you could use __PRETTY_FUNCTION__ in C++.
e.g:
void foo(int a, int b)
{
cout << __PRETTY_FUNCTION__ << endl;
}
outputs:
void foo(int, int)

If you want to make:
char *funct = "foo(bar)";
to actually call the function foo(), then its impossible, C just doesn't work that way. I would recommend that:
a) you sit down and rethink your application, because such behaviour shouldn't be needed for anything.
b) try a language with such capabilities, such as objective-c
c) if you really, really, really wanna do it... then make a string parser and lots of if's, or function pointers. Something in the lines of:
Get string in the form of "function(var1, var2, ..., varN)"
Get the name of the function (ie. everything before '(' )
Get all the parameters (strtok() for example)
Identify the function comparing constant names with your string ( strcmp() )
If the parameters are numeric ( isdigit() or sscanf( string, "%d", &parameter ) > 0 ) convert them to a usable primitive (atoi(), atof(), etc or sscanf())
Pass the params to your function.

If you want to execute a code from a string (I'm just guessing, your question is hard to understand), then there are many options available: from embedding the whole Clang and LLVM into your code (and making sure its JIT is aware of all your declarations you're going to export) to embedding a simple scripting language (like Lua or Guile) and providing wrappers for all the functions you want to call this way.

Related

Calling function with variable arguments dynamically

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.

Defining a function as a function pointer

Mostly for fun, I've decided to write my own minimal test framework for my C code. I use a basic struct for the test information, create an array of test structs and then iterate over them to run all the tests. This amounts to a very small amount of work for a fairly elegant (imho) solution.
However, the one thing that is a little annoying is that I cannot figure out how to define functions as function pointers instead of defining the function and then creating a function pointer later.
I have the following (which works just fine):
typedef int (* test_p) (void);
struct test {
char * desc;
test_p func;
};
int
example_test (void) {
puts("This is a test");
return 0;
}
void
run_test (char * test_name, test_p test) {
printf("Testing %s\t\t\t[ PEND ]\r", test_name);
char * test_result = (test() ? "FAIL" : "PASS");
printf("Testing %s\t\t\t[ %s ]\n", test_name, test_result);
}
int
main (void) {
struct test test_list [] = {
{ "example test", (test_p )example_test }
};
for ( int i = 0; i < 1; i ++ ) {
run_test(test_list[i].desc, test_list[i].func);
}
return 0;
}
However, I am hoping I can remove the need for the casting in the struct and instead define the function as being a function pointer from the beginning. The following is an example of how I would like this to work (assuming many of the same things as above):
test_p
example_test = {
puts("This is a test");
return 0;
}
If I could do something like this, then in the struct, I could simply have the func field be example_test rather than (test_p )example_test. Is this (or something like it) possible? If not, is there a reason why not (If that reason is simply "because it wasn't added to the language", that's fine)?
A function pointer is one kind of thing and a function is another kind of thing so you can't really make the latter be the former. But if you use a function name where a function pointer is expected, that produces a pointer to the function, so you can just remove the unnecessary cast, as WhozCraig said in the first comment above. You write
If I could do something like this, then in the struct, I could simply have the func field be example_test rather than (test_p )example_test.
You can do that, with example_test defined just as it is in your current code ... did you try that?
You can also forward declare a function, like so:
typedef int test_func(void); // note no indirection
typedef test_func* test_p;
test_func example_test;
It would be nice if you could use that sort of syntax when you define the function, as in your attempted syntax, but there's simply no way to do that in C ... you have to explicitly provide the return type and parameter list.
Another detail is that, when you invoke the function pointed to by a function pointer, you don't have to dereference it ... that's why you were able to write
test()
instead of
(*test)()
although the latter also works. (In fact, because the deference is stripped, (********test)() also works ... but only do that if you're trying to win an obfuscation contest.)
What you are describing is a kind of meta-programming. Rather than writing code to explicitly solve the problem, you are concerned with a kind of syntactic structure that will allow you to define a whole raft of test functions without unnecessary cruft.
In Lisp you would use macros. In C++ you might use templates and/or lambdas. In C you use macros.
So you need to write a macro that:
takes a name and descriptive text as arguments
defines a static variable of type function (created from that name using token pasting)
defines a function (using a name created by token pasting)
[edit] At this point you have achieved the goal: you have created the function and given it a name that is (only) a function pointer, and you can use that name in your struct without a cast. I would suggest one additional step, the macro also:
adds the variable/function and descriptive text to a list of functions to be tested.
Then your boilerplate loop iterates over the structure calling each function and reporting the results using the descriptive text. Problem solved.
Some people don't like macros, but they are ideally suited to this situation, and there is no other way to do it in C. I did something just like this before making the move to C++.

PostgreSQL module - How to map an array of parameters into the function?

Am trying to convert a little bit of C test code into a PostgreSQL v1 module
Code originally designed as a simple command line, which takes a variable number - an array - of text arguments; from 3 to 7
the original code's declarations are commented; I'm now trying to convert that into a PG shared object function. All of the arguments to the function will be text strings (base command, options, etc.)
how can I declare/pass the array into the function?
PG_FUNCTION_INFO_V1(embed_0);
Datum
embed_0(PG_FUNCTION_ARGS)
// THIS was the declaration when it was a C executable:
// int main(int argc, char *argv[])
{
// don't think mapping argc to a PG type is needed here, right?
// (argc is not a parameter?)
int *argc; // = PG_GETARG_INT32(0);
char argv[] = PG_GETARG_TEXT_P(0);
int i;
Object *pName, *pCall, *pPart1, *pPart2, *pArgs, *pValue;
If you have a variable number of arguments you need to either:
Declare it VARIADIC;
Create n different signatures for the function with different numbers of arguments; or
In C create only the most general form, the 7-argument variety, and then create SQL function wrappers for the fewer-arguments cases that call the most general form.
If you really only need 3,4,5,6, and 7-argument versions I'd do something like:
CREATE FUNCTION embed0(text,text,text,text,text,text,text) RETURNS text
LANGUAGE 'C' AS 'embed0','embed0';
CREATE OR REPLACE FUNCTION embed0(text,text,text) RETURNS text AS $$
SELECT embed0($1,$2,$2,NULL,NULL,NULL,NULL);
$$ LANGUAGE 'SQL';
// ... etc
If 7 args was just an arbitrary upper bound and you can actually take any number of arguments you should instead just write:
CREATE FUNCTION embed0(text,text,text,VARIADIC text) RETURNS text
LANGUAGE 'C' AS 'embed0','embed0';
and handle the variable arguments in your C function. See the PostgreSQL source code for the concat function for how. Its implementation is text_concat in src/backend/utils/adt/varlena.c on line 3842 in current git head; your line number will differ. Most of the work is done in concat_internal.
Another example is the format function, with C implementation text_format (via lookup in pg_proc.h), located in varlena.c (according to git grep '^text_format'; Pg coding style rules specify that the function name must begin on the hard left of the line), line 3953 in current git. While a more complicated function it might be better as an example for you because it does all the work in one place rather than splitting out for a helper function call. It's declared in pg_proc.h but if it were declared in SQL it'd look something like:
CREATE FUNCTION format(text, VARIADIC text) RETURNS text AS 'internal','text_format';
There you'll see that VARIADIC arguments are accessed like any other from C, using the PG_GETARG_...(argno) macros. The PG_NARGS() macro reports the number of arguments passed. VARIADIC arguments may be null so you have to use PG_ARGISNULL(argno) and handle the case of a null argument.
So: I'd write it as a VARIADIC function using PG_NARGS, PG_GETARG_TEXT_P, PG_ARGISNULL. Because Pg's VARIADIC functions cannot be called implicitly with zero variadic arguments, I'd write a wrapper for the 3-argument case that does:
CREATE OR REPLACE FUNCTION embed_0(text,text,text) RETURNS text AS $$
SELECT embed_0($1,$2,$2, VARIADIC ARRAY[]::text[]);
$$ LANGUAGE 'SQL';
, passing an empty array as the variadic parameter. That way you can call it with 3 args too.
BTW, when coding be aware that the string in a Pg text is not null terminated, unlike those passed to main(). You must use the lengths PostgreSQL provides.. See src/include/fmgr.h, the tutorial, and the text handling in the functions in the source code. Don't use strlen, strcat, strcpy, etc because they expect null-terminated strings.

Function pointer with default parameter in C

See, I have two functions, one to get a char, and other to put a char like this.
void function_get_char (input);
void function_put_char (output);
I have a function pointer to these functions like this.
void (*function_operators[])(input_or_output) = {function_get_char, function_put_char};
I need of, when I'll call my function_operator, I want to don't need to specify if I want to get it in of output or of my input.
Do I need to build my function pointer like this?
void (*function_operators[])(input_or_output) = {function_get_char(input), function_put_char(output)};
How can I do it?
Thanks in advance.
NOTE
input or output parameter, is not run_time parameter.
I'm not really sure what you want to do, but if you want to fix input and output to some predefined value (since you say they are not runtime parameters), the easiest solution should be to write some wrapper functions that call the "real" functions with the correct parameters. For example:
void fixed_get_char(void) { function_get_char(input); }
void fixed_put_char(void) { function_put_char(output); }
void (*function_operators[])(void) = {fixed_get_char, fixed_put_char};
You will have to create a function with no arguments which wraps the call to the function with an argument. If you need to do this at runtime, then look at (one of the definitions of) thunk or trampolines.

dlsym/dlopen with runtime arguments

I am trying to do something like the following
enum types {None, Bool, Short, Char, Integer, Double, Long, Ptr};
int main(int argc, char ** args) {
enum types params[10] = {0};
void* triangle = dlopen("./foo.so", RTLD_LAZY);
void * fun = dlsym(triangle, ars[1]);
<<pseudo code>>
}
Where pseudo code is something like
fun = {}
for param in params:
if param == None:
fun += void
if param == Bool:
fun += Boolean
if param == Integer:
fun += int
...
returnVal = fun.pop()
funSignature = returnval + " " + funName + "(" + Riffle(fun, ",") + ")"
exec funSignature
Thank you
Actually, you can do nearly all you want. In C language (unlike C++, for example), the functions in shared objects are referenced merely by their names. So, to find--and, what is most important, to call--the proper function, you don't need its full signature. You only need its name! It's both an advantage and disadvantage --but that's the nature of a language you chose.
Let me demonstrate, how it works.
#include <dlfcn.h>
typedef void* (*arbitrary)();
// do not mix this with typedef void* (*arbitrary)(void); !!!
int main()
{
arbitrary my_function;
// Introduce already loaded functions to runtime linker's space
void* handle = dlopen(0,RTLD_NOW|RTLD_GLOBAL);
// Load the function to our pointer, which doesn't know how many arguments there sould be
*(void**)(&my_function) = dlsym(handle,"something");
// Call something via my_function
(void) my_function("I accept a string and an integer!\n",(int)(2*2));
return 0;
}
In fact, you can call any function that way. However, there's one drawback. You actually need to know the return type of your function in compile time. By default, if you omit void* in that typedef, int is assumed as return type--and, yes, it's a correct C code. The thing is that the compiler needs to know the size of the return type to operate the stack properly.
You can workaround it by tricks, for example, by pre-declaring several function types with different sizes of return types in advance and then selecting which one you actually are going to call. But the easier solution is to require functions in your plugin to return void* or int always; the actual result being returned via pointers given as arguments.
What you must ensure is that you always call the function with the exact number and types of arguments it's supposed to accept. Pay closer attention to difference between different integer types (your best option would be to explicitly cast arguments to them).
Several commenters reported that the code above is not guaranteed to work for variadic functions (such as printf).
What dlsym() returns is normally a function pointer - disguised as a void *. (If you ask it for the name of a global variable, it will return you a pointer to that global variable, too.)
You then invoke that function just as you might using any other pointer to function:
int (*fun)(int, char *) = (int (*)(int, char *))dlsym(triangle, "function");
(*fun)(1, "abc"); # Old school - pre-C89 standard, but explicit
fun(1, "abc"); # New school - C89/C99 standard, but implicit
I'm old school; I prefer the explicit notation so that the reader knows that 'fun' is a pointer to a function without needing to see its declaration. With the new school notation, you have to remember to look for a variable 'fun' before trying to find a function called 'fun()'.
Note that you cannot build the function call dynamically as you are doing - or, not in general. To do that requires a lot more work. You have to know ahead of time what the function pointer expects in the way of arguments and what it returns and how to interpret it all.
Systems that manage more dynamic function calls, such as Perl, have special rules about how functions are called and arguments are passed and do not call (arguably cannot call) functions with arbitrary signatures. They can only call functions with signatures that are known about in advance. One mechanism (not used by Perl) is to push the arguments onto a stack, and then call a function that knows how to collect values off the stack. But even if that called function manipulates those values and then calls an arbitrary other function, that called function provides the correct calling sequence for the arbitrary other function.
Reflection in C is hard - very hard. It is not undoable - but it requires infrastructure to support it and discipline to use it, and it can only call functions that support the infrastructure's rules.​​​​
The Proper Solution
Assuming you're writing the shared libraries; the best solution I've found to this problem is strictly defining and controlling what functions are dynamically linked by:
Setting all symbols hidden
for example clang -dynamiclib Person.c -fvisibility=hidden -o libPerson.dylib when compiling with clang
Then using __attribute__((visibility("default"))) and extern "C" to selectively unhide and include functions
Profit! You know what the function's signature is. You wrote it!
I found this in Apple's Dynamic Library Design Guidelines. These docs also include other solutions to the problem above was just my favorite.
The Answer to your Question
As stated in previous answers, C and C++ functions with extern "C" in their definition aren't mangled so the function's symbols simply don't include the full function signature. If you're compiling with C++ without extern "C" however functions are mangled so you could demangle them to get the full function's signature (with a tool like demangler.com or a c++ library). See here for more details on what mangling is.
Generally speaking it's best to use the first option if you're trying to import functions with dlopen.

Resources