William Everett
William Everett

Reputation: 781

Is there a clean way in c to make a function that calls other functions with varied arguments?

I am writing an interface for a library and I have a lot of code blocks that look like this:

result = library_function(arg1, arg2, arg3,...,argn);
printf("library_function result: %s", result_to_string(result));

I'd really like to be able to do something more like:

function_caller(&library_function, arg1, arg2, arg3,...,argn);

or

function_caller(&library_function(arg1, arg2, arg3,...,argn));

I know how to set up the pointer to another function, but don't know how to parse an unknown number of unknown types of parameters. I can do this with typecasting, but that's less appealing than the current situation, which I admit isn't terrible, just kind of ugly looking.

Upvotes: 1

Views: 52

Answers (2)

On Linux (and some other systems) you could also use libffi.

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.

LibFFI knows about the precise Application Binary Interface conventions (for Linux x86-64 documented here) and is able to mimic the calling convention for any function (you'll need to specify at runtime the interface of that function).

If your library is big and is used a lot you could even consider customizing GCC thru MELT with an extension which automagically transform the gimple call to some functions (e.g. some kind of aspect programming). This may take a week of work.

Upvotes: 0

Dietrich Epp
Dietrich Epp

Reputation: 213258

Sigh1. Unless you know the argument types, you can do this with a macro.

#define function_caller(func, ...) do { \
    result = func(__VA_ARGS__); \
    printf("%s result: %s\n", #func, result_to_string(result)); \
} while (0)

You use it like this:

function_caller(library_function, arg1, arg2, arg3, arg4);

There are other ways to do it, but they are quite non-portable. The macro requires C99. C99 support is everywhere these days, but despite the standard's age, MSVC still lacks C99 support.

1 "Sigh" because I am suggesting a macro. Macros should generally be avoided, and can result in code that is difficult to read.

Upvotes: 2

Related Questions