Need to remove extra argument at function call - c

This is my typedef struct
//command look up table structure
typedef struct
{
int commandCode;
int (*process_command) (...);
}cmdTableStruct;
Using int (*process_command) (...); i need to call appropriate function which i have assign to that if command code match.
ex.
static cmdTableStruct cmdTable[]=
{
{ 1123,testFunc},
// more command in same manner
};
here it will call testFunc function if command code 1123 and argument of this function only one. Same it will call different functions but the argument type is different and argument is one.
Now using int (*process_command) (...); in stuct definition it give me error like
Error: #xx: expected a type specifier
I can resolve this error by adding one known type argument
like
int (*process_command) (int x,...);
But i don't want additional argument, i just want it will take one argument and call function with appropriate data type of argument.
is any suggestions?

Posting my comment as an answer, u can consider this:
typedef struct
{
int commandCode;
int (*process_command) (void *ptr);
}cmdTableStruct;
Make the argument to process_command to void *. Pass address of variable of whatever types you need for any specific case. Within each function, typecast to expected, copy to local variables of expected types and use.

Related

Using right pointer type, dont want to cast with void *

Question regarding using the correct pointer type in my below code. When I try to initialize struct member function without type casting to void *, I got “initialization from incompatible pointer type” warnings ?
problem solved by typecasting but I want to use right pointer type instead of casting to void*.
Code snippet:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef void (*set_id)(int id);
typedef void (*set_name)(char *name);
typedef struct prop {
set_id *cb_setting_id;
set_name *cb_setting_name;
}prop;
prop *setting_id(int id) {
printf("ID:%d\n", id);
}
prop *setting_name(char *in) {
char *name;
name = in;
printf("Name:%s\n", name);
}
//Here type casted to void *, if not I get wrong pointer initalization
//error
prop cb_prop = { .cb_setting_id=(void *)setting_id,
.cb_setting_name=(void *)setting_name };
int main() {
prop *cb_event;
cb_event = &cb_prop;
cb_event->cb_setting_id = (void*)setting_id(2);
cb_event->cb_setting_name = (void*)setting_name("/dev/ttyS1");
return 0;
}
Without type casting, Warning are:
struct_callback.c:25:33: warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
prop cb_prop = { .cb_setting_id=setting_id,
^
struct_callback.c:25:33: note: (near initialization for ‘cb_prop.cb_setting_id’)
struct_callback.c:32:26: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
cb_event->cb_setting_id = setting_id(2);
Check the definition of e.g. the set_id type alias, it is a pointer to a function taking an int argument and not returning anything. Then compare it with the setting_id function, which is a function that takes an int arguments and returns a pointer to prop. Those two types are not compatible. It's made even worse because the setting_id function is declared to return a pointer to prop but doesn't actually return anything.
And not only that, but the members in the structure are pointers to e.g. set_id which means that cb_setting_id is a pointer to a pointer to a function.
Later on you do
cb_event->cb_setting_id = (void*)setting_id(2);
This is wrong because it calls the setting_id function, and tries to assign the returned value to cb_event->cb_setting_id. But the setting_id function doesn't return anything.
The solution to the first problem is to make sure that both the set_id type and the function setting_id are equal.
The solution to the second problem is to not declare the members are pointers (since they already are), or by changing set_id to not be a pointer.
The solution to the third problem is to remove those lines, since the the first two solutions should solve the initial initialization of the cb_prop structure.
The types you're assigning to are incompatible.
The function setting_id is of type prop *(*)(int), but the cb_setting_id field is of type void (*)(int). Simiarly for setting_name.
You need to change the typedef to match the function. Also, you have one extra level of indirection in your struct definition than you need.
typedef struct prop prop;
typedef prop *(*set_id)(int);
typedef prop *(*set_name)(char *);
struct prop {
set_id cb_setting_id;
set_name cb_setting_name;
};
First of all your function pointer typedef does not match the actual functions, because you use different return types. But here you hide the pointer syntax behind a typedef:
typedef void (*set_id)(int id);
typedef void (*set_name)(char *name);
Therefore, these become pointer-to-function-pointer:
set_id *cb_setting_id;
set_name *cb_setting_name;
That's not what you want. Simply change the typedefs to:
typedef prop* set_id (int id);
typedef prop* set_name (char *in);
Please note that you are not allowed to cast a function pointer to/from a void*. Void pointers assume object pointers, not function pointers. So casting a function pointer to void* results in an invalid pointer conversion.

pointers to functions, with flexible types

I write a code with a connectivity list of a flexible type.
My database contains a list of nodes with data that might be a char* or a VERTEX* (struct defined by me). hence I defined the struct as with a field void*.
I also wish to have an operation which compares the strings in that field, so the list has a field defined:
DATA_EQ DataEqual
and defined a function which checks if the data of two nodes is equal:
typedef BOOL (*DATA_EQ) (void* pl, void* pr);
in order to define a DATA_EQ function for the list, in the case of string data, I created the following function in the .c file:
static BOOL stringDataEqual(char* pd1, char* pd2){
return ( strcmp(pd1, pd2) == 0 );
}
Finally, I want this function to be defined on my list, so I wrote:
pList->dataEqual = stringDataEqual;
but I guess the fact that I tried to specify the void* as char* is not good.
I haven't worked with pointers to functions in the past, so I might have done some silly mistakes...
I got the warning (after running gcc to complie):
warning: passing argument 1 of ‘ListCreate’ from incompatible pointer type [enabled by default]
I need my code to compile without any warnings, how do I solve/work around that?
Thanks ahead to anyone who helps,
Oded
Use casts to cast to and from void pointers. Your function becomes:
static BOOL stringDataEqual(void* pd1, void* pd2) {
return ( strcmp((char*)pd1, (char*)pd2) == 0 );
}
You can call this function by casting the parameters to void*.

Not getting correct value in structure

might be it's silly question but not getting what is wrong in my code.
I am writing simple command parser in which it will initialize appropriate parameters and call appropriate functions related to command code.
Ex.
char buffer[]="1123,13,46";
In above line 1123 is command code and rest of two tokens are parameters. In parser it will first find command code form command table and if command found then it will initialize structure of that command with above parameters.
Currently in my code i am successfully fetching correct command from command table and call that command's functions but failed to initialize the parameters with above values (13 and 46 here).Always getting 0.
As per below code same thing i want in my command parser but little modification
typedef struct
{
void *fields[2];
}tmpStruct;
typedef struct
{
int x;
int y;
}myStruct;
tmpStruct tmp_struct;
myStruct *getParams(tmpStruct *t_struct)
{
myStruct *genericStruct = malloc(sizeof(myStruct));
//setup the order of the fields in the handler
t_struct->fields[0]=(void*)&genericStruct->x;
t_struct->fields[1]=(void*)&genericStruct->y;
return genericStruct;
}
void *fillValue(tmpStruct *t_struct)
{
void *genericStruct;
genericStruct = getParams(t_struct);
*((int*)t_struct->fields[0])=12;
*((int*)t_struct->fields[1])=13;
return genericStruct;
}
void pritValue(myStruct *my_struct)
{
printf("%d %d\n",my_struct->x,my_struct->y);
}
int main()
{
void *genericStruct;
genericStruct = fillValue(&tmp_struct);
pritValue(genericStruct);
return 0;
}
Please find my working source file here
And header file here
The problem is that you are casting function pointers to types of functions that take different parameter types. Trying to make calls to functions through pointers like that is undefined behavior. Although you could potentially get away with calls that are similar - say, return myStruct* in place of void* pointer (although it's still undefined behavior), there is no way you could cast a function that takes an int and a myStruct* to a function type that takes an int and a variable list of arguments.
Changing your functions to the correct signatures to match cmdTableStruct table fixes this problem:
void *setParams(paramHandler_type *pHandler);
int printParams(int commandType,... );
static cmdTableStruct cmdTable[]=
{
{ 1123,setParams,printParams },
//more command in same manner
};
Demo.
Of course now you need to handle parameters from the ... list individually using the functionality from the <stdarg.h> header.
Also, the way you dereference param handler when assigning values is incorrect - the index should be applied to paramValue, not to pHandler:
*((int*)pHandler->paramValue[j]) = (int)atoi(token);

Modifying method to accept different type of parameters in C programming

typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
} struct1;
typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
int struct_variable_2c;
} struct2;
typedef struct1 *struct1_ptr;
typedef struct2 *struct2_ptr;
static void sampleFunction(struct1_ptr valueToInsert){
//this code does some stuff here
}
int main(){
struct1_ptr struct1_var = (struct1_ptr) malloc(sizeof(struct1));
strcpy(struct1_var->struct_variable_1a, "some value");
strcpy(struct1_var->struct_variable_1b, "some value");
sampleFunction(struct1_var);
return 0;
}
I have a sample code in C programming as shown above. In the main method, I am trying to pass a variable of type struct1_ptr for sampleFunction method call.
This works like a charm. But when I want to pass a variable of type struct2_ptr, the compiler is throwing error. Basically, I am java developer. I want to reuse this sampleFunction method for any variable type in its parameter in general. Kindly help me in this.
You could emulate inheritance in C like this:
typedef struct
{
char struct_variable_1a[10];
char struct_variable_1b[12];
} struct1;
typedef struct
{
struct1 parent; /* Must be first element! */
int struct_variable_2c;
} struct2;
And then call like this:
sampleFunction((struct1_ptr)ptr_to_struct2);
or (I would favor this, because there's no cast):
sampleFunction(&ptr_to_struct2->parent);
Just note that you won't be able to access members of struct2 in function without casting it back.
These work for simple structures, but if you do anything more complex, using C++ would be more approriate.
unfortunately C does not support method overloading / polymorphism. So you have to write your own methodology.
one is, to give the type as a first parameter to every overloaded function. Inside the function you walk along with a simple switch-case to jump to the original function implementation (like struct1_sampleFunction() and struct2_sampleFunction()).
another is, to put an RECORDCORE struct at the beginning of every struct and fill the type into this RECORDCORE, so each function can dispatch according to this data.
in both cases you have to change the prototype from "struct1_ptr value" to "void *value"
change your function from:
static void sampleFunction(struct1_ptr valueToInsert){
//this code does some stuff here
}
to:
static void sampleFunction(void* valueToInsert){
//this code does some stuff here
}
If you want to identify the type of the structure add a second parameter to your function that contains the size of the struct.
//Edit:
Inside the function you have to cast your variable back to the structure you want to use. for example:
strcpy(((struct1_ptr)valueToInsert)->struct_variable_1a, "some value");

How do you pass a typedef struct to a function?

At the moment I'm trying
void avg(everything)
But that gives me the error:
error: subscripted value is neither array nor pointer
And when I got this error earlier today it was because I wasn't passing a 2D array to the function properly. So I figure this is the same but I can't find the correct format to pass it in.
This is my typedef:
typedef struct structure
{
char names[13][9];
int scores[13][4];
float average[13];
char letter[13];
} stuff;
And this is my typedef array:
stuff everything[13];
In the function signature, you need to specify the type, not the specific name of a variable you want to pass in. Further, if you want to pass an array, you need to pass a pointer (you should probably be passing structs by pointers anyway, otherwise a copy of the data will be made each time you call the function). Hence you function should look like:
void avg(stuff* s);
However, C arrays also have no concept of length. Hence, you should always pass in the length of the array to the function:
void avg(stuff* s, size_t len);
You'd then call this as follows:
avg(everything, 13);
Also, if the function doesn't modify the data in any way, you should signify this by specifying that the parameter is const:
void avg(const stuff* s, size_t len);
A type introduced with typedef is an alias that can be used for a real type.
For example:
typedef struct some_struct { ... } some_type_name;
Now you can use some_type_name instead of struct some_struct.
So when declaring a function which takes a structure of this "type" you use the type like any other type:
void some_function(some_type_name var) { ... }
In some_function as defined above, you can use var like a normal structure variable.
To define a function taking an array (or a pointer) to this type, that's equally simple:
void some_function(some_type_name *pointer) { ... }

Resources