Array of functions with built in arguments in C - c

Say I have these two functions and a definition of an array of these two functions:
int flag;
int add(int a, int b){
return a+b;
}
int multiply(int a, int b){
return a*b;
}
typedef int(*f)(int, int);
f func_array[2] = {&add, &multiply};
Now, there is a specific place in my code that I want to call these two functions depending on my flag state with the same arguments each time.
For example:
int var;
if(flag == 0)
{
var = func_array[flag](1,1);
}
else{
var = func_array[flag](2,2);
}
Is there a way to define it inside the array itself? Somwhow defining the array like this and just call the function:
f func_array[2] = {&add(1,1), &multiply(2,2)};
int var = func_array[flag]();
Is this a valid way? Is there any more elegant way to do it?

You can define a set of arrays for each parameter:
#define ARR_SIZE 2
typedef int(*f)(int, int);
f func_array[ARR_SIZE] = {&add, &multiply};
int param1_array[ARR_SIZE] = { 1, 2};
int param2_array[ARR_SIZE] = { 1, 2};
The call would become
if(flag < ARR_SIZE)
{
int var = func_array[flag](param1_array[flag], param2_array[flag]);
}
I just added a check on the array size.
With a macro
#define flag_call(flag) \
func_array[flag](param1_array[flag], param2_array[flag])
you could simplify it even more
if(flag < ARR_SIZE)
{
flag_call(flag);
}

Not sure what the point is but you can do this:
int add11(void){ return add(1,1); }
int multiply22(void){ return multiply(2,2); }
/*skipped the new typedef*/
int (*func_array2[2])(void) = {&add11,&multiply22};
https://godbolt.org/z/ejMn4n
The wrappers could even be inlinable if you make the array static or auto.

You can use a struct to bundle them together:
typedef int(*f)(int, int);
struct func_and_args {
f func;
int a;
int b;
}
...
struct func_and_args arr[] = {{&add,1,1},{&multiply,2,2}};
int var = arr[flag].func(arr[flag].a,arr[flag].b);

Related

Dart C Interoperability. Pass an array of integers to C function

I am learning Dart now and I playing with Dart's Interoperability with C. I am able to use a C method with two int params. Code below:
hello.dart
import 'dart:ffi' as ffi;
typedef sum_func = ffi.Int32 Function(ffi.Int32 a, ffi.Int32 b);
typedef Sum = int Function(int a, int b);
...
final dylib = ffi.DynamicLibrary.open(path);
final sumPointer = dylib.lookup<ffi.NativeFunction<sum_func>>('sum');
final sum = sumPointer.asFunction<Sum>();
print('3 + 5 = ${sum(3, 5)}');
hello.c
int sum(int a, int b){
return a + b;
}
hello.h
int add(int x, int y)
hello.def
LIBRARY hello
EXPORTS
sum
This all works really well, but I also want to have an max C method, which takes an int array as an input and returns the biggest number. How can I do this? I've implemented all the required code in C, but I am not sure how do I "link" it with Dart. Could anyone help me please?
First, I really want to say that I am not a C programmer and especially when it comes to pointers I am not even pretending I have a fully understanding of how to do this kind of things the most optimal way.
With this out of the way here is my solution based on the primitives example found here: https://github.com/dart-lang/samples/tree/master/ffi/primitives
primitives.dart
import 'dart:ffi';
import 'dart:io' show Platform;
import 'package:ffi/ffi.dart';
typedef max_func = Int32 Function(Pointer<Int32> list, Int32 size);
typedef Max = int Function(Pointer<Int32> list, int size);
void main() {
var path = './primitives_library/libprimitives.so';
if (Platform.isMacOS) path = './primitives_library/libprimtives.dylib';
if (Platform.isWindows) path = r'primitives_library\Debug\primitives.dll';
final dylib = DynamicLibrary.open(path);
final list = [1, 5, 3, 59030, 131000, 0];
final listPtr = intListToArray(list);
final maxPointer = dylib.lookup<NativeFunction<max_func>>('max');
final max = maxPointer.asFunction<Max>();
print('${max(listPtr, list.length)}'); // 131000
malloc.free(listPtr);
}
Pointer<Int32> intListToArray(List<int> list) {
final ptr = malloc.allocate<Int32>(sizeOf<Int32>() * list.length);
for (var i = 0; i < list.length; i++) {
ptr.elementAt(i).value = list[i];
}
return ptr;
}
primitives.h
int max(int *listPtr, int size);
primitives.c
#include "primitives.h"
int max(int *listPtr, int size)
{
int currentMax = *listPtr;
for (int i = 0; i < size; i++)
{
if (currentMax < *listPtr)
{
currentMax = *listPtr;
}
listPtr++;
}
return currentMax;
}

How to print cascaded names of functions pointers?

I was working of functions pointers examples and I developed 4 simple functions and assigned them to a function pointer array, then I ran the code and worked for the 4 functions, but then I thought to also print the names of the functions.
I learned about __func__ and it only prints the name of the current function, so is there anyway to assign __func__ to the function pointer or another method to print the names of the functions?
This is the example I'm working on right now:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);
int main() {
int m = 6;
int n = 10;
int res,i;
int (*fun[4])(int,int)={add,sub,mul,divide};
for (i=0;i<4;i++)
{
printf("result of %s operation\n",__func__=fun[i]);
}
}
int add(int x, int y) {
int result = x + y;
return result;
}
int sub(int x, int y) {
int result = x - y;
return result;
}
int mul(int x, int y) {
int result = x * y;
return result;
}
int divide(int x, int y) {
int result = x / y;
return result;
}
As you can see I'm trying to assign the __func__ to the functions pointer but of course it's not working.
The __func__ constant in every function is only accessible in runtime. Meaning that if you want to use that one, you have to grab it while calling the function. Like this:
typedef int calc_func_t (int x, int y, const char** func);
int add(int x, int y, const char** func);
...
calc_func_t* fun[4] = {add,sub,mul,divide};
for (i=0;i<4;i++)
{
const char* func;
int result = fun[i](1,1,&func);
printf("result of %s operation %d\n", func, result);
}
...
int add(int x, int y, const char** func)
{
int result = x + y;
*func = __func__;
return result;
}
...
If you wish to know what the functions are named at compile-time and then later on use that information, the easiest and best way would be to create a look-up table:
typedef struct
{
calc_func_t* func;
const char* name;
} calc_func_info_t;
const calc_func_info_t func_info [] =
{
{add, "add"},
{sub, "sub"},
...
};
Compiled code doesn't contain functions and symols names by default. You can use some macros to create constant strings containing functions names to be included in the compiled binary:
#include <stdio.h>
// function call type
typedef void fn_call();
// record describing one function
typedef struct fn_record {
const char *name; // function's name as a constant string
fn_call *call; // function call
} fn_record;
// the functions to be called and named
void fna() { printf("called fna\n"); }
void fnb() { printf("called fnb\n"); }
void fnc() { printf("called fnc\n"); }
// macro, that generates record for each function, it creates
// string like { "fna", fna } to save You typing
#define FN_RECORD(f) { #f, f }
// now define array of functions records
fn_record fns[3] = {
FN_RECORD(fna),
FN_RECORD(fnb),
FN_RECORD(fnc)
};
// ... which becomes:
// fn_record fns[3] = {
// { "fna", fna },
// { "fnb", fnb },
// { "fnc", fnc }
// };
int main(void) {
int i;
// ... use it whatever You like
for (i = 0; i < 3; i++) {
printf("%s\n", fns[i].name);
fns[i].call();
}
return 0;
}
Basically, there is no way.
// A function declaration
void MyFunction(void);
// a pointer to the function
void (*fnPointer)(void) = MyFunction;
// No way to retrieve function name "MyFunction" from fnPointer
Ofcourse, if you have a known set of possible functions that might be assigned to the pointer, you could compare them explicitely.
Also, you can change the stored function pointer to be combined with the function name. Could be something similar to the following:
struct FunctionPointerContainer
{
void (*fnPointer)(void);
char* fnName;
};
#define MakeFunctionPointer(fn) FunctionPointerContainer { fn, #fn }
// later
struct FunctionPointerContainer myPointer = MakeFunctionPointer(MyFunction);
myPointer.fnPointer(); // call
myPointer.fnName; // the function name
I was working of functions pointers examples
So, as I understand, your example is done for educational purposes, aren't you? In that case I would do it as simple as it can be to not confuse the students who use your example to learn how function pointers work.
I learned about __func__ and it only prints the name of the current function
Despite other answers show very nice and smart solutions how to have the function name outside of it, from the perspective of simplicity I would still use the __func__ as it normally works, inside the called function:
#include <stdio.h>
#define print_info(format, ...) \
printf("Function '%s' is called with parameters: "format"\n", \
__func__, __VA_ARGS__)
int add(int x, int y);
int sub(int x, int y);
int mul(int x, int y);
int divide(int x, int y);
int main() {
int m = 6, n = 10, i;
int (*fun[4])(int,int) = { add, sub, mul, divide };
for (i = 0; i < 4; ++i)
printf("-- result is: %d\n", fun[i](n, m));
return 0;
}
int add(int x, int y) {
print_info("%d, %d", x, y);
return x + y;
}
int sub(int x, int y) {
print_info("%d, %d", x, y);
return x - y;
}
int mul(int x, int y) {
print_info("%d, %d", x, y);
return x * y;
}
int divide(int x, int y) {
print_info("%d, %d", x, y);
return x / y;
}

Passing inputs to a function from a list of inputs without hard-coding it in C

Suppose I have a function:
void add(int a, int b , int c);
and I have an array which contains 3 integer values:
int L[] = {1,2,3};
Now I want to pass these values to add without writing add(L[0],L[1],L[2]).
I mean is there a way of creating a Single input from multiple inputs and passing it to the function which will treat that single input as multiple inputs ??.
You could try this
int L[] = {1,2,3};
add(L, 3);
where
void add(int *x, int length)
{
// use x[0], x[1], etc.
}
But I am not sure why you are having problem with your current approach.
Another option would probably be to encapsulate those three integers into a structure and pass the structure along.
If you mean something like Python
def foo(a, b, c):
return a + b + c
x = (1, 2, 3)
print(foo(*x)) # the '*' does the magic of calling foo with 1, 2, 3
then this is not possible in portable C.
What you can do is change the interface of foo to accept an array of arguments, e.g.
int sum(int *data, int n) {
int tot = 0;
for (int i=0; i<n; i++) {
tot += data[i];
}
return tot;
}
can call it with
int x[] = {10, 20, 30, 40};
int res = sum(x, 4);
If you cannot change the function definitions and you have many of them with the same signature what you can do is use function pointers to factor out the call:
int sum3(int a, int b, int c) {
return a+b+c;
}
int mul3(int a, int b, int c) {
return a*b*c;
}
int call_int_int3(int(*f)(int, int, int), int* args) {
return f(args[0], args[1], args[2]);
}
...
int data[] = {10, 20, 30};
int sum = call_int_int3(sum3, data);
int prod = call_int_int3(mul3, data);
but you will need a different wrapper for each distinct signature (number and type of arguments and type of return value).

Accessing array of function pointers

Following is the array of function pointers
(int) (*a[5]) (int);
int f1(int){};
...
is the following way of definition correct?
a = f1;
a + 1 = f2;
a + 2 = f3;
...
how do we call these functions?
*a(1) // is this correct???
*(a+1) (2)
#include <stdio.h>
int f1(int i) { return i; }
int f2(int i) { return i; }
int main() {
int (*a[5]) (int);
a[0] = f1;
a[1] = f2;
printf("%d\n", a[0](2));
printf("%d\n", a[1](5));
}
What you call "definition" is just assignment, and as you are doing it, it is wrong, since you can't assign to arrays in C. You can only assign to individual array elements, correct would be a[0] = f1 etc.
Often for arrays of function pointers there is no need to assign them dynamically at run time. Function pointers are compile time (or link time) constants anyhow.
/* in your .h file */
extern int (*const a[5]) (int);
/* in your .c file */
int (*const a[5]) (int) = { f1, f2, f3 };
To simplify using function pointers a bit, the identifier for a f1 is equivalent to a pointer to the function &f1 and using a function pointer with parenthesis as in a[0](5) is the same as dereferencing the pointer and calling the resulting function (*(a[0]))(5).
you can write:
a[0]=&f1;
and call it as below:
a[0](1);
note that there is no need to use a pointer while the function is getting called.
If you insist on using a pointer, then you can anyhow do the below:
(*a[0])(1);
It is always better to use typedefs, (and all your functions need to have a common interface anyway and also to initialise at declaration time, where possible function arrays should also be const as a safety measure so:
#include <stdio.h>
typedef int (*mytype)();
int f1(int i) { return i; }
int f2(int i) { return i; }
int main() {
const mytype a[5] = {f1,f1,f2,f2,f1};
printf("%d\n", a[0](2));
printf("%d\n", a[1](5));
return 0;
}
#include<stdio.h>
int (*a[5]) (int);
int f1(int i){printf("%d\n",i); return 0;}
int f2(int i){printf("%d\n",i); return 0;}
int f3(int i){printf("%d\n",i); return 0;}
int main(void)
{
a[0] = f1; // Assign the address of function
a[1] = f2;
a[2] = f3;
(*a[0])(5); // Calling the function
(*a[1])(6);
(*a[2])(7);
getchar();
return 0;
}

Adding (or doing any other math) every member of two same structs with less code

So, basically, I want to addify every member of first struct, with every member of second struct, and the structs are of same type. Like this:
struct Foo
{
int bar1;
int bar2;
int bar3;
int bar4;
int bar5;
}
Foo AddFoos(Foo foo1, Foo foo2)
{
Foo foo3;
foo3.bar1 = foo1.bar1 + foo2.bar1;
foo3.bar2 = foo1.bar2 + foo2.bar2;
foo3.bar3 = foo1.bar3 + foo2.bar3;
foo3.bar4 = foo1.bar4 + foo2.bar4;
foo3.bar5 = foo1.bar5 + foo2.bar5;
return foo3;
}
However, when structs keep getting bigger, this way is weird. Is there any way to do it with less lines of code? And preferably without advanced pointer magic?
Use an array instead and a for loop to add the numbers:
struct Foo
{
int bars[100];
};
for (i=0;i<100;i++)
{
foo3.bars[i]=foo1.bars[i]+foo2.bars[i];
}
You can malloc if the array size is unknown at compile time and change the struct to this and then malloc for all three Foo variables.
struct Foo
{
int *bars;
};
You want the comfort of named fields (bar1 .. barN) and something like an array you can loop over to automate the operations. First we define the struct (a dense representation of the fields in memory):
struct VectorFields {
int a;
int b;
int c;
};
Then we need to get to know the number of the fields used in that struct:
#define VECTOR_FIELDS_LEN (sizeof(struct VectorFields) / sizeof(int))
(In C++ you could use some template magic foo, here we just use the preprocessor as a simpler variant). Next, we combine the struct VectorFields with an array of int so both match in size, also known as union:
union Vector {
struct VectorFields fields;
int raw[VECTOR_FIELD_LEN];
};
(Note: VECTOR_FIELD_LEN must be a known constant value to the compiler, hence the preprocessor thingy before.) You are now able to access the data either by it's name (.fields.a) or by an index (.raw[0]). So, let's write the function which adds the Vector together:
void vector_add(union Vector* result, union Vector* a, union Vector* b) {
int i;
for (i = 0; i < TUPLE_LEN; i++) {
result->raw[i] = a->raw[i] + b->raw[i];
}
}
You might use it like this then:
#include <stdio.h>
int main() {
union Vector a = { .fields = { 1, 2, 3 } };
union Vector b = { .fields = { 4, 5, 6 } };
union Vector sum;
vector_add(&sum, &a, &b);
printf("%d %d %d\n", sum.fields.a, sum.fields.b, sum.fields.c);
return 0;
}
Depending on what you call "advanced pointer magic", you can use the following moderately magical code:
Foo AddFoos(Foo foo1, Foo foo2)
{
Foo foo3;
int *pointer1 = &foo1.bar1; // first field here
int *pointer2 = &foo2.bar1; // first field here
int *pointer3 = &foo3.bar1; // first field here
while (pointer3 <= &foo3.bar5) // last field here
{
*pointer3++ = *pointer1++ + *pointer2++;
}
return foo3;
}
When you change the definition of Foo, just update the names of the first and last field.
This will only work when all fields are of the same type.
If you have only ints you can use an array
struct Foo {
int bar[5];
};
Foo AddFoos(Foo f1, Foo f2)
{
Foo f3;
int i;
for (i = 0; i < 5; ++i)
f3.bar[i] = f1.bar[i] + f2.bar[i];
return f3;
}

Resources