C - passing function with arguments into wrapper executor - c

Is there a way to build a wrapper function in C as follows:
void wrapper(void *func) {
// Set up
func([same arguments as func was passed in with]);
// Clean up
}
void foo(int x, int y);
void bar(char *z);
wrapper(foo(1, 2));
wrapper(bar("Hello"));
It seems as though you have to either pass in the arugments within wrapper or only support one type of method header for func. I've been writing a lot of Javascript... and of course this is possible in JS.

That's the best I can think of with variadic function wwrappers:
#include <stdio.h>
#include <stdarg.h>
void wrapper(void (*func)(va_list), ...) {
va_list args;
va_start(args, func);
func(args);
va_end(args);
}
void foo(int x, int y)
{
printf("foo(%d,%d)\n", x, y);
}
void vfoo(va_list args)
{
foo(va_arg(args, int), va_arg(args, int));
}
void bar(char *z)
{
printf("bar(%s)\n", z);
}
void vbar(va_list args)
{
bar(va_arg(args, char*));
}
int main()
{
wrapper(vfoo, 1, 2);
wrapper(vbar, "Hello, World!");
return 0;
}
Live example on Coliru.

Have you considered (ab)using the preprocessor?
#include <stdio.h>
#define wrapper(f) /* Set up */\
f; \
/* Clean up */
void foo(int x, int y) {
printf("x: %d; y: %d\n", x, y);
}
void bar(char *str) {
printf("str: %s\n", str);
}
int main(void) {
wrapper(foo(42, 11));
wrapper(bar("hello world"));
}
To elaborate upon why I added the possibility of an ab- prefix to (ab)use, I wouldn't hesitate to use whatever is the most expressive solution to a problem, regardless of the attitude held by the general populus. However, I recognise that sometimes we have no control over the restrictions we are bound by, and policies are often put in place to heavily restrict the use of macros. Unfortunately, those bound by such silly policies won't find this post too helpful.
In a comment above I suggested that "if you want a feature from Javascript you should probably write your code in Javascript...".
Upon pondering about this overnight, I came to the conclusion that features similar to those you ask are actually doable and would be quite nice in C... so I admit, I was wrong.
The following is an example of mimicking how Javascript treats functions.
#include <stdio.h>
struct argument;
typedef struct argument argument;
typedef void function(argument *);
struct argument {
function *function;
/* for foo() */
int x;
int y;
/* for bar() */
char *str;
};
void wrapper(argument *a) {
// set up
a->function(a);
// clean up
}
void foo(argument *a) {
printf("x: %d; y: %d\n", a->x, a->y);
}
void bar(argument *a) {
printf("str: %s\n", a->str);
}
#define foo(...) wrapper(&(argument){ .function = foo, __VA_ARGS__ })
#define bar(...) wrapper(&(argument){ .function = bar, .str = "", __VA_ARGS__ })
int main(void) {
foo(.x = 42, .y = 11);
bar(.str = "hello world");
}
There are actually some really nice features coming from this style of wrapper:
It becomes very difficult for a down-stream programmerr to mung the stack, where-as it is very easy for programmers using typical variadic functions such as printf and scanf to cause subtle yet devastating bugs by passing the wrong types and/or values to those functions. This leads on to my next point:
Default argument values are possible by simply modifying the foo and bar macros. As an example in the code above, the default value for the argument named str is set to "" (an empty string) for bar.
By introducing extra logic into wrapper, you can mimic partial function application (or binding properties to functions, much like you'd see in Javascript). Additionally, with a little bit of effort, mimicking continuation passing style might be possible by turning wrapper into a trampoline-style function and modifying the return value? I'll ponder more on this and provide an update tomorrow.
Finally, down-stream users are encouraged to pair argument identifiers with argument values, which improves maintainability drastically.
There are some minor draw-backs, the most significant being that neither foo nor bar can be passed, unapplied, to another function as an argument. This would be rare for these functions specifically, as they differ greatly in signature, but for functions that are identical or even similar in signature I can understand one might want to pass them as callbacks or what-not.
The solution to that problem is to rename the macros to default_foo and default_bar or something like that...
Finally, thanks for asking such a thought-provoking question... I hope reading my answer has been as interesting for you as thinking about (and writing) it was for me.

Related

Passing a dynamic set of variadic arguments to a C function [duplicate]

This question already has answers here:
In C, given a variable list of arguments, how to build a function call using them?
(4 answers)
Closed 4 years ago.
I'm trying to call a C function that takes variadic arguments, and I need to pass in a dynamic number of arguments to the function. Additionally, this is an API I can't modify without going to a lot of effort, so if there's any possible to make this work I'll take it.
As far as I can tell, va_list is not sufficient for this purpose since you can't pass a va_list where ... was written in the original function signature.
Answers for other questions like this one talk about how to pass a ... from one function to another, but that's not what I'm doing. I need to actually dynamically generate the list of arguments, I'm not getting it in as a .... Also, all the answers I can find rely being able to modify the function to take a va_list, which is not an option here.
There was also this question, which was marked as a dupe of the previous question despite not actually asking the same question. Again, the only answer suggests converting the call to use va_list which is not an option.
I would understand if the standard didn't include a way to do this, but this seems like a case where I can imagine a perfectly reasonable implementation. This isn't so different from, say, alloca. Anyway, if it's not possible, that's fine, but I'd like the SO community to realize that this isn't a dupe of this question and deserves a definitive answer.
The API I'm calling is in C, but if there's a way to do this in C++ I would consider it.
Edit: If you have these requirements, it looks like this answer using libffi is the best way to go. There does not appear to be a way to do this either in standard C or with GCC extensions otherwise.
If you use gcc compiler, you can use __builtin_va_arg_pack() or __builtin_apply(), see here.
Examples:
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
int my_printf(const char *fmt, ...)
{
void *args = __builtin_apply_args();
void *ret = __builtin_apply((void(*)())printf, args, 100);
__builtin_return(ret);
}
extern int my2_printf(const char *, ...);
extern inline __attribute__((__always_inline__,__gnu_inline__))
int my2_printf(const char *fmt, ...) {
return printf(fmt, __builtin_va_arg_pack());
}
int main()
{
my_printf("%s %s %s %s %s\n", "Hi", "I", "am", "kamil", "!");
my2_printf("%s %s %s %s\n", "Variadic", "args", "are", "fun");
return 0;
}
#edit:
As the question is also about on how to construct a dynamic argument list and then pass it to function. You can create a function for each case you need to support and use a big switch to differentiate between them.
A example for printing an array of unknown compile size:
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
#include <stdlib.h>
#include <boost/preprocessor/repetition/repeat.hpp>
void print_array(size_t cnt, ...)
{
va_list va;
va_start(va, cnt);
printf("%s cnt=%d :", __func__, cnt);
for (size_t i = 0; i < cnt; ++i) {
printf(" %d", va_arg(va, int));
}
va_end(va);
printf("%s\n");
}
// we support an array up to that many arguments
#define CALL_PRINT_ARRAY_MAX 128
#define CALL_PRINT_ARRAY_ARGS(z, n, text) \
, arr[n]
#define CALL_PRINT_ARRAY_DECLARE(z, n, text) \
void call_print_array_##n (int arr[]) \
{ \
print_array(n BOOST_PP_REPEAT(n, CALL_PRINT_ARRAY_ARGS, ())); \
}
BOOST_PP_REPEAT(CALL_PRINT_ARRAY_MAX, CALL_PRINT_ARRAY_DECLARE, ())
#undef CALL_PRINT_ARRAY_DECLARE
#undef CALL_PRINT_ARRAY_ARGS
int call_print_array(int arr[], size_t n)
{
switch(n) {
#define CALL_PRINT_ARRAY_CASE(z, n, text) \
case n: call_print_array_##n(arr); break;
BOOST_PP_REPEAT(CALL_PRINT_ARRAY_MAX, CALL_PRINT_ARRAY_CASE, ())
#undef CALL_PRINT_ARRAY_CASE
default:
fprintf(stderr, "Array size is too big for what we're prepared\n");
return -1;
}
return 0;
}
int main()
{
//int a1[5] = {1,2,3,4,5};
//call_print_array(a1, sizeof(a1)/sizeof(a1[0]));
size_t size;
scanf("%zu", &size); // insecure
int * a2 = calloc(size, sizeof(*a2));
for (size_t i = 0; i < size; ++i)
a2[i] = i;
call_print_array(a2, size);
return 0;
}
The easiest way to do this would be with variadic macros, kind of like the way it's done for eprintf:
#define eprintf(…) fprintf (stderr, __VA_ARGS__)
__VA_ARGS__ expands into the full argument list passed into the macro with which you can then call the other function declared with .... Unfortunately what you want to do cannot be done within a function without going through a lot of effort that you seem to want to avoid.

How can I pass an array as a list of args to a function with varying number of parameters in C

I wonder how can I tease out an array in C to several arguments of a function.
After I saw the amazing syntatic sugar from Go (golang) I thinking about it.
The c code:
#include <stdio.h>
#include <stdarg.h>
// assert: all args are valid ints
void printEach(int len, ...) {
// Irrelevant, this function print their arguments
// And I know how to use va_start, va_arg...
}
void handleVet(int* v, int n) {
// **HERE is my the question!!!**
printEach(n, v[0]...[n]) // <----------- NON-C code. I need it.
}
int main(void) {
int v[] = {12,14,15,15};
//I can do that only because the vector is static. I know the len when I'm coding
printEach(4, v[0],v[1],v[2],v[3]);
// But if we imagine an arbitrary vector, we got a problem
handleVet(v, 4);
return 0;
}
By Example, in go it would be:
package main
import "fmt"
func printEach (v ...int64) {
// Irrelevant, this function print their arguments
}
func main() {
var arr []int64 = []int64{1,14,15,}
printEach(arr...)
}
How can I achieve the same effect of "printEach(arr...)" in C?
This is a rudimentary example on how vararg is working in C.
I wasn't able to take refference to your go example as I don't udnerstand what your code does. I hope this minimal example is clear enough. If you have any questions ask me and I will edit it in.
void Foo(size_t sizeParamAmount, char *types, ...);
void Foo(size_t sizeParamAmount, char *types, ...)
{
size_t i;
float fTmp;
int iTmp;
va_list vlArgList;
va_start (vlArgList, sizeParamAmount);
for (i= 0; i< sizeParamAmount; i++)
{
switch (types[i])
{
case 'i':
iTmp = va_arg (vlArgList, int));
break;
case 'f':
fTmp = va_arg (vlArgList, float));
break;
default:
return;//error
}
}
va_end(vlArgList);
}
After reading your edit:
As I already did in my minimal example, you can hand in a pointer before the var_arg's which is explaining which argument is of what type. so you could call Foo this way:
Foo (3, "ifi", 3, 5.973, 92);
And after reading your comment to another answer I got what you are asking about.
In that case you really jsut should hand in a pointer (or array without [] behaves for this case the same) which holds an end content token.
Anyway there is a way. but you had to freak around with preprocessing tokens.
And would be totally over the top for your needs. This answer would anyway give you the requested notation. you had to set for PRED a limit by sizeof(yourarray) and the let OP take the single elements.
https://stackoverflow.com/a/10542793/2003898
But there is sadly not a more minimal example.
You will need to specify the size of the array. Here's what it might look like:
void printEach(int* values, int size)
{
if(size==0)
return;
printf("%d", value[0]);
printEach(values+1, size-1);
}
You are looking for Variadic function, you should look at
stdarg.h and varargs.h

How do I bind arguments to a C function pointer?

I have done some research about how to use function pointers in C and I was trying to do some model of an object-oriented kind of thing. So to model such a thing I have been told I would have to add function pointers to the structs, so that they would be kind of 'an object'.
As I am pretty new on programming in C, this question may seem a little stupid (or very easy to answer), but on the Internet, I just found examples concerning C++ and that's not what I am searching.
Here is an example I would like to show, so that you can easily understand what my question is about:
try.h-file:
struct thing {
void (*a)(int, int);
};
void add(int x, int y);
try.c-file:
#include <stdio.h>
#include <stdlib.h>
#include "try.h"
void add(int x, int y) {
printf("x + y = %d\n", x+y);
}
int main(int argc, char* argv[]) {
struct thing *p = (struct thing*) malloc(sizeof(struct thing));
p->a = &add;
(*p->a)(2, 3);
free(p);
p = NULL;
return 0;
}
As an example I would want to have always x = 2, so the function pointer in struct thing would be this kind of pointer: void (*a)(int) and not void (*a)(int, int) anymore.
How can I bind the argument x = 2 when passing the function pointer to the struct (line p->a = &add;)? Is this even possible in C? In C++ I have seen something like std::bind, but I wasn't able to do this in C.
The function pointer has to have the same signature (type and arguments) as the function it points to, so you can't really do it like that.
You could wrap the bind and the call in another couple of functions:
struct thing {
void (*a)(int, int);
int x;
};
...
void bind1st( struct thing *p, int arg )
{
p->x = arg;
}
void call( struct thing *p, int arg )
{
p->a( p->x, arg );
}
You'll want to experiment with this a bit, but that should get you started.
I've had similar problems,and I used the following method to resolve, use gcc to compile it work, use clang to compile it do not work.
#include <stdio.h>
typedef int (*add_t) (int);
add_t add2(int x) {
int add1(int y) {
return x + y;
}
return add1;
}
int main() {
//add2(2);
printf("%d\n", add2(2)(3));
}
A way that no one have talked about yet is to use some JIT logic (I won't provide a working example right now, because I've not yet tried it, but I will use it at some time for a RPC library). This is not strictly speaking a C language feature, and it's feasible only on CPU/MCU architecture where you can write to an executable memory segment (it's possible on x86_64, x86, some ARMs etc.).
The principle is really just to construct a function dynamically that will call the wrapped function in a similar way python defines dynamically nested functions.
Some library you can use for it : libgccjit, libjit, gnu-ligthning, llvm etc.
I think this is the best solution .
typedef void(*call_type)();
call_type bind(void (*f)(int,int), int a, int b) {
void call() {
f(a,b);
}
return &call;
}
void f(int a, int b){
printf("%d, %d", a, b);
}
int main(){
call_type c = bind(f, 5, 4);
c();
}

Function pointers, design

I am in a problem with a design question in C.
Let's say that I have a pretty large amount of functions, with different argument count.
POQ:
int print_one(int x)
{
printf("one: %d\n", x);
return 1;
}
int print_three(int x, int y, int z)
{
printf("three: %d-%d-%d\n", x, y, z);
return 3;
}
Now, I want to connect some properties to these functions in a structure, so that I can manipulate them without knowing the exact function, including their parameter count (I might even call the structure interface)
I tryd it like this, (& I think is pretty wrong):
typedef int (*pfunc)(int c, ...);
typedef struct _stroffunc
{
pfunc myfunction;
int flags;
int some_thing_count;
int arguments[10];
int argumentcount;
} stroffunc;
int main()
{
stroffunc firststruct;
firststruct.pfunc = (pfunc) print_two;
firststruct.something_count = 101;
arguments[0] = 102;
argumentcount = 1;
flag &= SOME_SEXY_FLAG;
// now I can call it, in a pretty ugly way ... however I want (with patially random results ofc)
firststruct.pfunc(firststruct.arguments[0]);
firststruct.pfunc(firststruct.arguments[0], 124, 11);
firststruct.pfunc(1, firststruct.arguments[0], 124, 1, 1);
}
I find this solution very ugly, & I think (hope) that there is a better solution for calling & and setting the function pointers.
I'm just hoping, that I was clear enough ...
NOTE: I didn't compile this code, but i compiled & run a very similar one so the concepts are working.
NOTE: pure C needed
Calling a non-variadic function through a variadic function pointer leads to undefined behaviour. For a start, recall that the arguments to variadic functions undergo the default argument promotions (chars are converted to ints, etc.), which will totally screw things up.
It's not clear how or why you intend to dynamically call a function with differing numbers of arguments. But one solution could be to use a union:
typedef struct {
int num_args;
union {
void (*f1)(int);
void (*f2)(int, int);
void (*f3)(int, int, int);
} func;
} magic;
...
magic m;
...
switch (m.num_args) {
case 1: m.func.f1(arg1); break;
case 2: m.func.f2(arg1, arg2); break;
case 3: m.func.f3(arg1, arg2, arg3); break;
default: assert(0);
}
A second solution would be to rewrite all of your functions as variadic.
This is on the edge of my knowledge, but I believe that you need to make the functions variadic as well, due to incompatibilities in the ABI.
see: wikipedia's example
Maybe you can add a library which have some functions to handle the struct, like a "pseudo" class,
int initFunc(int (*pfunc)(int c,...));
This function will save the pointer into the struct, like a context in POO, in the struct you will use it like a "map" of all the function an you will call each one using an id.
which returns an id, and you save it in an array,
then another func say
int call(int id,int p1,...);
where you say the function id and the parameters, sure you must now which function is each id

Given a char* with the prototype, can we cast a void* to a function pointer? and run it?

I've declared many functions in one driver, and am passing the pointers to the functions to another driver in a list with the node format:
struct node
{
char def_prototype[256]; //example:(int (*)(wchar, int, int))
void *def_function;
};
Is there a way to typecast def_function to the prototype given in def_prototype?
Currently I'm using simple switch and strcmp, but I wanted to generalize it if possible.
PS: I know that casting between void pointer and function pointer is unsafe (as mentioned in various places in SO), but desperate times call for desperate measures and I have taken lot of care.
EDIT:
Sorry for the lack in clarity. I want to actually call the function (not just cast it), making a function pointer at runtime based on the char[] provided.
EDIT AGAIN:
Since I'm working at the kernel level (windows driver), I don't have access to much resources, so, I'm sticking to my current implementation (with some changes to kill back-doors). Thanks to all for your help.
ISO-C does not allow casting between function and data pointers, ie you should use a void (*)(void) instead of a void * to hold your function.
That aside, YeenFei is correct in his assertion that there is no general platform-independant solution, meaning the best you can do in C itself is to supply a list of supported signatures.
You should implement your own encoding scheme instead of using plain C prototypes. It's common to use a string where each char represents a function argument (and the first one the return value); a function of type int (*)(wchar, int, int) for example could have the signature "iwii".
Signature lookup tables can then be easily built using bsearch() and strcmp(); here's a complete example:
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int cmp(const void *key, const void *element)
{
return strcmp(key, *(const char * const *)element);
}
static _Bool dispatch(const char *sig, void (*func)(void), void *retval, ...)
{
// supported signatures; must be ordered according to strcmp()
static const char * const SIGS[] = { "iii", "v", "vi" };
const char * const *match = bsearch(
sig, SIGS, sizeof SIGS / sizeof *SIGS, sizeof *SIGS, cmp);
if(!match) return 0;
va_list args;
va_start(args, retval);
switch(match - SIGS)
{
case 0: { // iii
int a1 = va_arg(args, int);
int a2 = va_arg(args, int);
int rv = ((int (*)(int, int))func)(a1, a2);
if(retval) memcpy(retval, &rv, sizeof rv);
break;
}
case 1: { // v
func();
break;
}
case 2: { // vi
int a1 = va_arg(args, int);
((void (*)(int))func)(a1);
break;
}
default:
assert(!"PANIC");
}
va_end(args);
return 1;
}
// example code:
static int add(int a, int b)
{
return a + b;
}
int main(void)
{
int sum;
dispatch("iii", (void (*)(void))add, &sum, 3, 4);
printf("%i", sum);
return 0;
}
unless you want to mess with assembly thunking (pushing data onto stack before jumping, etc), there is better way other than doing some switch case.
if the destination function is finite and known, why not create a lookup table (map<string, functor>) for it ?
A good implementation of similar ideas is libffi. This implements the gory details of declaring and calling functions with arbitrary calling conventions and signatures. It is (surprisingly) platform portable, and known to work on Linux and Windows out of the box.
An example of its use is the Lua extension library alien. That demonstrates calling arbitrary functions declared at runtime and adapting from native Lua types to the types required for the calling conventions. The specific Lua binding won't be useful to you, but it serves as a complete working example of how and why one might actually use libffi.
Since C has no runtime type information, there is absolutely no need to do a dynamic cast as you are considering. Just pass the pointer and if everything fits, it will work. If the pointer doesn't point to a function with the right signature, there is no way to fix it.
There are basically two solutions:
Go to the assembly level and parse the prototype string there and put the arguments you find in the prototype there where the other function will expect them.
Make a long list of all supported prototypes and compare the current one with the list. When you find a match, you can make the typecast as needed. The most common structure for this test would ba an if-else ladder.

Resources