C: Is it possible to create an array of Clang Blocks? - c

You probably know a feature of the Clang compiler called Blocks.
Is there a way to create an array of Blocks?
My attempt looks like this but it doesn't compile:
const void (^write_pckt_props)(const int, struct pckt_idntfy*)[] = {
^(const int prop_idx, struct pckt_idntfy *pckt) {
/* empty */
},
^(const int prop_idx, struct pckt_idntfy *pckt) {
/* empty */
}
};
And someone would be able to call it via write_pckt_props[i]().
Any ideas if that's possible at all?

Yes, it is possible. This is how it's done:
const void (^write_pckt_props[])(const int, struct pckt_idntfy*) = {
^(const int prop_idx, struct pckt_idntfy *pckt) {
/* empty */
},
^(const int prop_idx, struct pckt_idntfy *pckt) {
/* empty */
}
};
write_pckt_props[0](0, NULL);

Related

Variabe type for variable inside function

I'm having different different types of structs, which are going to be passed to a function which performs the same tasks on them.
int menu_parameter_arrow_print(game_setting_identifier* identifier, controller_direction direction, uint8_t position)
{
if((position > setting->alternatives_number) || position < 0)
{
#ifdef OLED_PRINT_DEBUG_ENABLE
OLED_debug_print("Out of bounds");
#endif
return RETURN_VALUE_FAILURE;
}
else
{
switch ((int)*identifier)
{
case ((int) GAME_SETTING_ANALOG):
game_setting_analog* setting = (game_setting_analog*)&identifier;
case ((int) GAME_SETTING_TOGGLE):
game_setting_toggle* setting = (game_setting_toggle*)&identifier;
case ((int) GAME_SETTING_VALUE):
game_setting_value* setting = (game_setting_value*)&identifier;
}
This function gives a conflicting type-error
The operations performed on the structs are the same, but the structs contains different types of members:
struct game_setting_analog
{
//Identifier for the game-setting type:
game_setting_identifier identifier;
//Alternatives:
char* alternatives[4];
};
typedef struct game_setting_value game_setting_value;
struct game_setting_value
{
game_setting_identifier identifier;
uint8_t* alternatives[6];
uint8_t alternatives_number;
};
typedef struct game_setting_toggle game_setting_toggle;
struct game_setting_toggle
{
//Identifier for the game-setting type:
game_setting_identifier identifier;
toggle_state* alternatives[2];
};
typedef struct game_setting_difficulty game_setting_difficulty;
struct game_setting_difficulty
{
game_setting_identifier identifier;
char* alternatives[3];
};
Actions will be performed on the 'alternatives'-member of the structs, even though these members are of different types.
Is there a solution to doing this without having to use one if-statement for each identifier?
Edit: With a modification to the switch-case, I'm able to get the initialization compiled. The variables inside the switch-scope is however not visible to the rest of the function
int menu_print_parameter_line(game_setting_identifier* identifier, controller* C, uint8_t position)
{
uint8_t next_position = position;
controller_direction previous_direction = C->joystick.generalDirection;
if ((identifier == NULL) || (C == NULL) || (position == NULL))
{
return -1;
}
switch((int) identifier)
{
case ((int) GAME_SETTING_ANALOG):
{
game_setting_analog* setting = (game_setting_analog*)identifier;
uint8_t alternatives_number = 4;
}
break;
case ((int) GAME_SETTING_TOGGLE):
{
game_setting_toggle* setting = (game_setting_toggle*)identifier;
uint8_t alternatives_number = 2;
}
break;
case ((int) GAME_SETTING_VALUE):
{
game_setting_value* setting = (game_setting_value*)identifier;
uint8_t alternatives_number = setting->alternatives_number;
}
break;
default:
{
return -1;
}
break;
}
#ifdef MENU_PARAMETER_ASSIGNMENT_DEBUG
OLED_debug_print("before switch-case");
#endif
switch (previous_direction)
{
case LEFT:
next_position -= 1;
if(next_position <= 0)
{
next_position = alternatives_number;
}
I personally don't like the inheritance model that depends on the first member of the structure, like the BSD socket library is using. Basically you are just trying to implement std::variant from c++ in C.
Is there a solution to doing this without having to use one if-statement for each identifier?
The object-oriented concept of interface works very nice and I believe is applicable in this case. It takes some C discipline to write it, but it works like a charm and you could be looking for it here.
I copied your definitions from which I removed typedefs because I don't like them:
struct game_setting_analog {
char* alternatives[4];
};
struct game_setting_value {
uint8_t* alternatives[6];
uint8_t alternatives_number;
};
struct game_setting_toggle {
toggle_state* alternatives[2];
};
struct game_setting_difficulty {
char* alternatives[3];
};
Let's first implement the interface abstraction with a function pointer that allows to get the alternatives number:
// forward definition
struct game_setting_s;
// the virtual table for game_settings
struct game_setting_vtable_s {
uint8_t (*get_alternatives_number)(struct game_setting_s *t);
// TODO: add other members, constructor, copy constructor, destructor, etc.
};
// represents any game_setting
// exposes a public interface to access and manipulate a game_setting
struct game_setting_s {
// the vtable is const, so it can save RAM
const struct game_setting_vtable_s *v;
// this is a pointer to private settings data
void *data;
};
// accessor for less (or more ;) typing
static inline
uint8_t game_setting_get_alternatives_number(struct game_setting_s *t) {
// alternative you could pass t->data to the function, I pass it all
// so that functions can modify the t->data member
// and also so that advanced functions usages can use like container_of macros
return t->v.get_alternatives_number(t);
}
Then you need to provide the virtual tables for each of the types. The definitions can be in separate types, so you can have a separate .c/.h file pair for each of the type, just exposing public interface.
// game_setting_analog --------------------
static
uint8_t game_setting_analog_get_altenatives_number(struct game_setting_s *t)
{
return 4;
}
const struct game_setting_vtable_s game_setting_analog_vtable = {
.get_alternatives_number = game_setting_analog_get_altenatives_number,
};
// game_setting_toggle --------------------
static
uint8_t game_setting_toggle_get_altenatives_number(struct game_setting_s *t) {
struct game_setting_toggle *data = t->data;
return data->alternatives_number;
}
const struct game_toggle_vtable_s game_setting_toggle_vtable = {
.get_alternatives_number = game_setting_toggle_get_altenatives_number,
};
// and so on...
Then your function takes just the interface and is very clear without any switch case:
int some_function_that_needs_to_know_which_setting_is_passed(struct game_setting_s *s) {
int number_of_alternatives = game_setting_get_alternatives_number(s);
}
Remember to construct the interface object properly and watch who owns the memory of the object. Let's construct a toggle and call out function:
struct game_settting_toggle memory;
// your function to initialize the toggle
game_setting_toggle_intialize(&memory);
// the interface is constructed with the proper vtable
// and a pointer to proper memory region with the data
struct game_setting_s any_setting = {
.vtable = game_setting_toggle_vtable,
.data = &memory,
};
// the initailize function could be in interface too
// so you would just call game_setting_initialize(&any_setting);
// with usage of dynamic allocation, you can just ex.
// struct game_setting_s *any_setting = game_setting_new_toggle();
// and write proper object-oriented factories
// finally call our function.
some_function_that_needs_to_know_which_setting_is_passed(&any_setting);
Case labels do not provide scopes for variables. All three setting variables within the switch have different types which are the conflicts the compiler. Use brackets to define scopes:
switch ((int)*identifier)
{
case ((int) GAME_SETTING_ANALOG):
{
game_setting_analog* setting = (game_setting_analog*)&identifier;
}
case ((int) GAME_SETTING_TOGGLE):
{
game_setting_toggle* setting = (game_setting_toggle*)&identifier;
}
case ((int) GAME_SETTING_VALUE):
{
game_setting_value* setting = (game_setting_value*)&identifier;
}
}
Also, you're not breaking in the cases, so the code in all three cases are run if ((int)*identifier == (int) GAME_SETTING_ANALOG)

A string inside a struct is being overwritten and I can't tell why

I've had this problem for the last two hours and I can't understand what's happening. I expect it to print this
ROBCO INDUSTRIES UNIFIED OPERATING SYSTEM
COPYRIGHT 2075-2077 ROBCO INDUSTRIES
-Server 6-
But instead it displays this
ROBCO INDUSTRIES UNIFIED OPERATING SYSTEM
COPYRIGHT Testing testing 123
I have no clue why this is happening but hopefully you will be able to help me. (If you want to know what this is for it's a Fallout Terminal Emulator). Just ask if you nned any more details. Thanks!
It's being compiled like this if you need to know
gcc test.c configParser.c -lconfig
test.c
#include <stdio.h>
#include "robco.h"
int main() {
struct config_struct config;
config = getConfig("test_config.cfg");
printf("%s", config.banner);
return 0;
}
configParser.c
#include <stdio.h>
#include <libconfig.h>
#include <string.h>
#include "robco.h"
int cap(int num, int cap) {
return (num > cap) ? cap : num;
}
struct config_struct getConfig(const char *filename)
{
config_t cfg;
config_setting_t *root, *menu, *options, *option;
// Read the file. If there is an error, report it and exit.
config_init(&cfg);
config_read_file(&cfg, filename);
root = config_root_setting(&cfg);
// Get the banner from the config file if it exists, if not use the default set in robco.h
const char *banner;
if (! config_setting_lookup_string(root, "banner", &banner) ) {
banner = DEFAULT_BANNER;
}
// Create the config struct and fill in the banner
struct config_struct config;
strcpy(config.banner, banner);
// Get the menu
menu = config_lookup(&cfg, "menu");
// If it can't fetch the menu for any reason return -1
if(! menu) {
return;
}
// Get the options
options = config_setting_get_member(menu, "options");
if(! options) {
return;
}
// Get number of options
config.menu.num_options = cap(config_setting_length(options), MAX_OPTIONS);
// Get the title. If it doesn't exist use the default
const char *title;
if (! config_setting_lookup_string(menu, "title", &title) ) {
title = DEFAULT_TITLE;
}
strcpy(config.menu.title, title);
// Loop through and get the text for all the options
for(int i = 0; i < config.menu.num_options; ++i)
{
option = config_setting_get_elem(options, i);
const char *text;
config_setting_lookup_string(option, "text", &text);
strcpy(config.menu.options[i].text, text);
}
return config;
}
robco.h
#define MAX_STRING_LENGTH 52
#define MAX_OPTIONS 5
#define DEFAULT_BANNER "ROBCO INDUSTRIES UNIFIED OPERATING SYSTEM\nCOPYRIGHT 2075-2077 ROBCO INDUSTRIES\n-Server 6-"
#define DEFAULT_TITLE "-=- TEST TITLE -=-"
struct option_struct {
char text[MAX_STRING_LENGTH];
};
struct menu_struct {
struct option_struct options[MAX_OPTIONS];
int num_options;
int selected;
char title[MAX_STRING_LENGTH];
};
struct config_struct {
char banner[MAX_STRING_LENGTH];
struct menu_struct menu;
};
void printCenter(char msg[], int startRow);
void printMenuOption(char msg[], int startRow);
void drawMenu(struct menu_struct menu, int startRow);
void init_graphics();
struct config_struct getConfig(const char *filename);
test_config.cfg
menu: {
title: "Super Secret Valve Control Panel";
options: (
{
text: "Testing testing 123";
},
{
text: "THE SUN IS A DEADLY LASER";
}
);
};
I bet your MAX_STRING_LENGTH is too little and that you don't test for lengths. You must use strncpy and then don't forget to set the terminating null, which strncpy doesn't do.
You must also turn the warnings of your compiler on. I see struct config_struct getConfig but in that function you do some returns without a return value. The compiler should warn about that.
Your default banner text is longer than MAX_STRING_LENGTH, so when you copy it to config.banner you write past the end of the array, leading to undefined behavior.
Make sure all your buffers are large enough to store the longest string you expect (accounting for the terminator), or truncate strings to the length of the buffer, or use dynamic memory and size the buffers as you need to.

How to include macro in struct

I am trying to find a way to dynamically access a certain macro in C.
I tried to include the macro in the struct but then I get the "initializer element is not constant" error. Basically I just want to access the correct macro based on an index but I just don't know how. Is there a straight forward way of accomplishing this? Please note the code is not complete but only an illustration of what I want to do.
#define Data_CAN_SES_Enbl() (...)
#define Data_CAN_SAS_Enbl() (...)
#define Data_CAN_PEP_Enbl() (...)
struct CAN_Rx {
const uint8 id;
const uint8 bus;
xx
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,0,?
},
/* SAS */
{
1,0,?
},
/* PEP */
{
2,1,?
}
};
void run(uint8 index)
{
uint8 enabled = CheckRx[index].xx;
}
Simply put: you won't.
Dont think of macros as code: they're just chunk of text replaced by the preprocessor before compiling your code.
If you need to embed code in a struct, you better look at function pointers.
--- EDIT ---
By the way, why you want to use macro in your code? Looking at it, it seems you cand do the same thing with a simple function returning a struct with a different content based on a parameter, like:
static struct CAN_Rx getCANrx(int index){
switch(index)
{
case '0':
struct CAN_rx res = /* initialize struct */;
return res;
case '1':
/* as previous */
default:
/* manage default result or errors */
}
}
Maybe you can go with function pointers?
#include <stdio.h>
int Data_CAN_SES_Enbl() { return 0; }
int Data_CAN_SAS_Enbl() { return 1; }
int Data_CAN_PEP_Enbl() { return 2; }
struct CAN_Rx {
const int id;
const int bus;
int (*xx)();
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,0,Data_CAN_SES_Enbl
},
/* SAS */
{
1,0,Data_CAN_SAS_Enbl
},
/* PEP */
{
2,1,Data_CAN_PEP_Enbl
}
};
int run(int index)
{
int enabled = (*CheckRx[index].xx)();
return enabled;
}
int main() {
printf("%d\n",run(0));
}
If you are curious see below macro example.
For your case , macro cant be better than function pointers.
Using macro just for fun at your case.
#include <stdio.h>
#include <stdlib.h>
#define Data_CAN_SES_Enbl(Y,Z) Y+Z
#define Data_CAN_SAS_Enbl(Y,Z) Y*Z
#define Data_CAN_PEP_Enbl(Y,Z) Y-Z
#define Str(X) #X
#define Data_CAN_Enbl(X,Y,Z) Data_CAN_##X##_Enbl(Y,Z);
#define SES 1
#define SAS 2
#define PEP 3
struct CAN_Rx {
int id;
int bus;
int Flag;
};
static struct CAN_Rx CheckRx[] = {
/* SES */
{
0,100,SES
},
/* SAS */
{
70,20,SAS
},
/* PEP */
{
100,50,PEP
}
};
void run(int index)
{
int RRR=0;
switch(CheckRx[index].Flag){
case SES:
RRR=Data_CAN_Enbl(SES,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(SES),RRR);
break;
case SAS:
RRR=Data_CAN_Enbl(SAS,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(SAS),RRR);
break;
case PEP:
RRR=Data_CAN_Enbl(PEP,CheckRx[index].id,CheckRx[index].bus);
printf("%s :%d\n",_Str(PEP),RRR);
break;
}
}
int main(){
run(0);
run(1);
run(2);
printf("%d\n",CheckRx[0].Flag);
return 0;
}

Array of jump tables in C

I'm trying to optimize access to some jump tables I have made, they are as follows:
int (*const usart_ctrl_table[USART_READ_WRITE_CLEAR])() =
{zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr};
int (*const usart_frame_table[USART_READ_WRITE_CLEAR])() =
{zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr};
int (*const usart_trig_ctrl_table[USART_READ_WRITE_CLEAR])() =
{zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr};
As you can see, the functions are for accessing a usart peripheral on a hardware level and are arranged in the table in the order of read/write/clear.
What I am attempting to do is have another jump table of jump tables, this way I can either run through initializing all the usart's registers in startup or simply change a single register later if desired.
i.e.
<datatype> (*usart_peripheral_table[<number of jump tables>])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
This way I can expose that table to my middleware layer, which will help maintain a standard across changing HALs, and also I can use a define to index this table i.e.
fn_ptr = usart_peripheral_table[CTRL_TABLE]
fn_ptr[WRITE](bitmask);
fn_ptr[READ](buffer);
As you may have already guessed, I am struggling to figure out how to construct this table. I figured it is one of two things:
Another simple array of pointers, as even a jump table itself is just an array of pointers. Hence my initialization would be:
const int* (*usart_peripheral_table[<number of jump tables])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
However this doesn't seem to be working. Then I thought:
An array of pointers to pointers. So I tried all kinds of combos:
const int**(*usart_perip...
const int**(usart_perip...
const int** (*usart_peripheral_table[<number of jump tables])() =
{&usart_ctrl_table, &usart_frame_table[0], usart_trig_ctrl_table};
Nothing seems to work. Do I need to store the address of the lower jump tables in yet another pointer before assigning that variable to a pointer-to-pointer array? i.e.
int* fn_ptr = usart_ctrl_table;
<dataytype>(*const usart_periph[<number>])() = {fn_ptr};
Thanks in advance, any help would be greatly appreciated.
MM25
EDIT:
const int** (*const peripheral_table[1])() =
{&usart_ctrl_table[0]};
const int** (*const peripheral_table[1])() =
{usart_ctrl_table};
The above both give the error "initialization from incomaptible pointer type", as do all other combinations I have tried
You might find that defining a typedef for your function pointers makes your code easier to read and maintain (although I’ve seen people recommend against it too):
#include <stdio.h>
#include <stdlib.h>
#define UART_RWC 3U
typedef int (*uart_ctl_func)(void);
int uart_read(void)
{
printf("Read.\n");
fflush(stdout);
return 0;
}
int uart_write(void)
{
printf("Write.\n");
fflush(stdout);
return(0);
}
int uart_clear(void)
{
printf("Clear.\n");
fflush(stdout);
return 0;
}
uart_ctl_func uart_ctl_jump_table[][UART_RWC] = {
{ uart_read, uart_write, uart_clear },
{ uart_read, uart_write, uart_clear }
};
int main(void)
{
uart_ctl_jump_table[0][1](); // Write.
uart_ctl_jump_table[1][0](); // Read.
uart_ctl_jump_table[1][2](); // Clear.
return EXIT_SUCCESS;
}
The next step might be to make the jump table a struct so you end up writing Uart_ctl_table.frame.read(), or to at least define an enum for the constants.
#include <stdio.h>
#include <stdlib.h>
#define UART_RWC 3U
typedef int (*uart_ctl_func)(void);
int uart_read(void)
{
printf("Read.\n");
fflush(stdout);
return 0;
}
int uart_write(void)
{
printf("Write.\n");
fflush(stdout);
return(0);
}
int uart_clear(void)
{
printf("Clear.\n");
fflush(stdout);
return 0;
}
typedef struct {
uart_ctl_func read;
uart_ctl_func write;
uart_ctl_func clear;
} uart_ctl_set_t;
typedef struct {
uart_ctl_set_t ctrl;
uart_ctl_set_t frame;
uart_ctl_set_t trig;
} uart_ctl_table_t;
const uart_ctl_table_t uart_ctl_table = {
.ctrl = { uart_read, uart_write, uart_clear },
.frame = { uart_read, uart_write, uart_clear },
.trig = { uart_read, uart_write, uart_clear }
};
int main(void)
{
uart_ctl_table.ctrl.write(); // Write.
uart_ctl_table.frame.read(); // Read.
uart_ctl_table.trig.clear(); // Clear.
return EXIT_SUCCESS;
}
Just add a * like you added [] when defining an array.
int zg_usartCtrlRead();
int zg_usartCtrlWrite();
int zg_usartCtrlClr();
int zg_usartFrameRead();
int zg_usartFrameWrite();
int zg_usartFrameClr();
int zg_usartTrigctrlRead();
int zg_usartTrigctrlWrite();
int zg_usartTrigctrlClr();
int (*const usart_ctrl_table[])() =
{zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr};
int (*const usart_frame_table[])() =
{zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr};
int (*const usart_trig_ctrl_table[])() =
{zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr};
int (* const * const usart_peripheral_table[])() =
{usart_ctrl_table, usart_frame_table, usart_trig_ctrl_table};
Usage:
usart_peripheral_table[1][2](5, 1, 3, 5, 6);
Btw, an empty parameter list on function declaration () means unspecified number and type of arguments. Do (void) if you want no arguments passed to your function.
This:
const int* (*usart_peripheral_table[<number of jump tables])();
Is an array of functions pointers that take unspecified number of arguments and return a pointer to constant integer.
This:
const int** (*usart_peripheral_table[<number of jump tables])()
Is an array of function pointers that take unspecified number of arguments and return a pointer to a pointer to a constant integer.
You can also go with a 2D array:
int (* const usart_peripheral_table_2d[][3])() = {
{
zg_usartCtrlRead, zg_usartCtrlWrite, zg_usartCtrlClr,
}, {
zg_usartFrameRead, zg_usartFrameWrite, zg_usartFrameClr,
}, {
zg_usartTrigctrlRead, zg_usartTrigctrlWrite, zg_usartTrigctrlClr,
},
};
But maybe you want to write accessor functions that will return a pointer to an array of functions. Nothing simpler!
#include <stddef.h>
int (*usart_ctrl_table_get(size_t idx))() {
return usart_ctrl_table[idx];
}
int (*usart_frame_table_get(size_t idx))() {
return usart_frame_table[idx];
}
int (*usart_trig_ctrl_table_get(size_t idx))() {
return usart_trig_ctrl_table[idx];
}
int (* const (* const usart_peripheral_table_indirect[])(size_t))() = {
usart_ctrl_table_get,
usart_frame_table_get,
usart_trig_ctrl_table_get,
};
Usage sample:
int main() {
usart_peripheral_table_indirect[2](1)();
}

How to wrap function pointer in plain C

Is it possible to "wrap" a function pointer in C somehow, similar to what you would do with a lambda in C#?
Actual problem I am having is:
I have a couple of functions with different parameters:
// more than two in actual code
void DoStuff(void) { ... }
void DoOtherStuff(int) { ... }
...and I want to create a couple of threads to run these in a loop:
// this won't work because it expects a LPTHREAD_START_ROUTINE,
// which is int(*fn)(void*)
tHnd1 = CreateThread(NULL, 0, &DoStuff, NULL, 0, &tId);
tHnd2 = CreateThread(NULL, 0, &DoOtherStuff, NULL, 0, &tId);
In C#/C++ I would use a lambda, or a pointer to a method which would call the other one, but I have no clue how to do this in C, unless I manually create wrapper functions:
int CallDoStuff(void *dummy) { DoStuff(); return 0; }
int CallDoOtherStuff(void *dummy) { DoOtherStuff(42); return 0; }
Is there any other way to avoid doing this step?
Nope, there's really no other way than to create the wrapper functions. And remember they have to return a value as well. If you don't wrap (or forget to return a (dummy) value) you will have UB.
You can create structure which will contain function type, function pointer and arguments if needed. Thread function would have to check function type and then call function using appropriate signature and pass parameters stored in structure. You can also create helper functions used to create these structures to simplify coding. Below is example code for two possible function types (with void and int arg):
#include <stdio.h>
#include <stdlib.h>
/* Few types needed to store function pointer and arguments in struct */
typedef enum FuncType
{
F_Void,
F_Int,
} FuncType;
typedef void(*VoidFuncPtr)(void);
typedef void(*IntFuncPtr)(int);
typedef struct FuncWrapper
{
FuncType funcType;
union
{
VoidFuncPtr voidFunc;
IntFuncPtr intFunc;
};
union
{
int intArg;
};
} FuncWrapper;
/* Thread func which can handle different functions */
void ThreadFunc(void* arg)
{
FuncWrapper* wrapper = (FuncWrapper*)arg;
switch (wrapper->funcType)
{
case F_Void:
wrapper->voidFunc();
break;
case F_Int:
wrapper->intFunc(wrapper->intArg);
break;
}
free(wrapper);
}
/* Helper functions used to create FuncWrapper instances */
FuncWrapper* wrapVoidFunc(VoidFuncPtr func)
{
FuncWrapper* wrapper = (FuncWrapper*)malloc(sizeof(FuncWrapper));
wrapper->funcType = F_Void;
wrapper->voidFunc = func;
return wrapper;
}
FuncWrapper* wrapIntFunc(IntFuncPtr func, int arg)
{
FuncWrapper* wrapper = (FuncWrapper*)malloc(sizeof(FuncWrapper));
wrapper->funcType = F_Int;
wrapper->intFunc = func;
wrapper->intArg = arg;
return wrapper;
}
/* Dummy StartThread func, which simply calls passed in function */
typedef void(*ThreadFuncPtr)(void*);
void StartThread(ThreadFuncPtr funcPtr, void* data)
{
funcPtr(data);
}
/* Functions which will be called */
void myVoidFunction(void)
{
printf("myVoidFunction called\n");
}
void myIntFunction(int arg)
{
printf("myIntFunction called, arg = %d\n", arg);
}
/* Finally the main func */
int main()
{
StartThread(ThreadFunc, wrapVoidFunc(myVoidFunction));
StartThread(ThreadFunc, wrapIntFunc(myIntFunction, 22));
return 0;
}

Resources