when I had a look on the sources of opensc, especial the libpkcs11.c file, I found a type declaration combined with a function call which I just don't understand:
CK_RV rv, (*c_get_function_list)(CK_FUNCTION_LIST_PTR_PTR);
c_get_function_list = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) sc_dlsym(mod->handle, "C_GetFunctionList");
I know that:
CK_RV is a typedef for unsigned long
CK_FUNCTION_LIST_PTR_PTR is a typedef for something like **ck_function_list where ck_function_list is a struct
rv is a variable
c_get_function_list is a variable
But if I split the first line and substitute the typedefs with their original values , I get something like:
unsigned long rv;
unsigned long (*c_get_function_list)(**ck_function_list);
So, what does the (**ck_function_list) in the second line mean ?
Thanks in advance,
Robert
unsigned long (*c_get_function_list)(<param>);
is a function pointer to a function whose prototype is.
unsigned long func(<param>);
The pointer here is c_get_function_list
c_get_function_list is pointer to function. When assigned, you can call the pointed function like normal function call: c_get_function_list( param ).
Related
A part of the C program that I am writing includes initialization of an input table using sc_memset() function. The table is defined by a typedef struct as shown below.
typedef struct {
UINT32 switchnum;
UINT32 feedback[8];
UINT32 switch_output[8];
} SWITCH_CHECK_IN;
SWITCH_CHECK_IN switch_input_table;
All the table elements, that is switchnum, feedback and switch_output should be initialized to zero.The sc_memset function prototype to be used for initialization is :
extern void sc_memset (volatile unsigned char *dest, unsigned long n, unsigned char data);
I have written the initialization code and because of the type differences in SWITCH_CHECK_IN & volatile unsigned char, I have tried to do some casting as below (I have tried several cast statements) but everytime I get a 'passing arg 1 of sc_memeset from incompatible pointer type' error.
while( *(volatile unsigned char *) &switch_input_table) {
{
sc_memset( &switch_input_table, sizeof(switch_input_table), 0 );
}
I'm new to C so I am not quite sure if my general approach is correct. Kindly,
1. Where am I going wrong? Could you please show me the correct way.
2. What other methods can be used?
Thanks in advance.
You need to cast the pointer to struct into a pointer to unsigned char, just like you do in the while condition:
sc_memset( (unsigned char*)&switch_input_table, ...
You shouldn't need volatile in the cast - the function implicitly adds volatile type qualifier to the passed parameter. Why it has volatile, I have no idea - it's fishy code unless the function expects a hardware register etc as input.
So usually I would declare any function pointer like this:
typedef size_t (*hash_function)(const int *);
and then later use it in another function
HashTable *hash_table_create(const hash_function hash)
so for any function which fulfills the hash_function definition like
size_t hash_modulo(const int *parameters)
size_t hash_universal(const int *parameters)
...
I can use them as a parameter
hash_table_create(hash_modulo)
The problem is: My IDE (Clion) complains that the parameters in this case do not match (the code works tho). Specifically it doesn't seem to accept passing hash_function as a parameter type, but will accept if I use size_t (*hash_function)(const int *) instead. What am I missing here?
Is my code right and my IDE wrong or vice versa?
Thanks in advance!
Edit 1: The exact error message is: Types 'hash_function' and size_t(const int *)' are not compatible
Edit 2: This seems to be a Clion Bug
CLion seems to have a bug (possibly). The function names are of the type size_t(const int *). Now, since functions are implicitly convertible to function pointers, your code is perfectly valid C.
The CLion syntax checker probably doesn't take implicit conversions into account. If you obtain a function pointer explicitly from the function name the error should go away:
hash_table_create(&hash_modulo); // Note the ampersand
I think the problem is that you typedef the function as const
HashTable *hash_table_create(const hash_function hash)
and the other functions you want to put in as parameters aren't declared const
size_t hash_modulo(const int *parameters)
size_t hash_universal(const int *parameters)
Edit:
This works fine in CodeBlocks
Change this:
size_t hash_modulo(const int *parameters)
size_t hash_universal(const int *parameters)
into this:
hash_function hash_modulo;
hash_function hash_universal;
and then this work fine:
hash_table_create(hash_modulo);
hash_table_create(hash_universal);
Explanation in the comment below.
I have this part in instructions of my school project:
In hw_numbers.h define type hw_number_array (for passing arguments to functions by reference). To store numbers in that array, use array of unsigned long.
My friend gave me hint, that it should look like this:
typedef unsigned long hw_number_array[];
Can someone explain me, why should I use this for passing an array to function?
And how can this type even exist without defining actual size of array?
If the size of the array is omitted, this is called an array of unknown bound. There are only certain places where this can be used, but a function parameter is one of them. There is a special rule that says even if a bound is given for an array, the bound is ignored and the parameter is equivalent to a pointer:
void f(int []) // this means void f(int *)
C++ inherited this rule from C. Some programmers consider it helpful for documenting that it is intended that an array is passed for the parameter as opposed to a pointer to a single value.
When calling such a function, it appears that you can pass an array by reference:
{
int a[5];
f(a); // actually passes an int pointer
}
But this is actually an illusion. The array decays to a pointer, and then a pointer is passed instead.
Here's some code you can try:
typedef unsigned long hw_number_array[];
int main()
{
unsigned long myArray[100];
setValue(myArray, 5, 10);
unsigned long value = getValue(myArray, 5);
return 0;
}
unsigned long setValue(hw_number_array a, int index, unsigned long value)
{
a[index] = value;
}
unsigned long getValue(hw_number_array a, int index)
{
return a[index];
}
I have been going through the Atmel library USB for AT91SAM7 and there is something I don’t understand. Endpoint is a structure defined as follows:
typedef struct {
volatile unsigned char state;
volatile unsigned char bank;
volatile unsigned short size;
Transfer transfer; //thus Endpoint contains an instance of "Transfer"
} Endpoint
point;
And Transfer itself is a structure as follows:
typedef struct {
char *pData;
volatile int buffered;
volatile int transferred;
volatile int remaining;
volatile TransferCallback fCallback;
void *pArgument;
} Transfer;
And TransferCallback is a function with the following prototype:
typedef void (*TransferCallback)(void *pArg, unsigned char status, unsigned int transferred, unsigned int remaining);
also two pointers have been defined as the following:
Endpoint *pEndpoint = &(endpoints[bEndpoint]);
Transfer *pTransfer = &(pEndpoint->transfer);
I want to know why such a way to call the function TransferCallback is valid:
((TransferCallback) pTransfer->fCallback) (followed by the required arguments passed )
But this is not valid:
((TransferCallback)pEndpoint->transfer->fCallback)?
how could I directly call TransferCallback without using a pointer such as pTransfer in between?
I tried a number of combinations but none worked.
Note that Endpoint does not have a pointer to Transfer member (*Transfer), but a Transfer member. In machine terms, rather than a single word of memory within each Endpoint being used as a pointer to a Transfer, all the fields of the Transfer member are stored directly inside the memory allocated for the Endpoint.
To cut to the chase, what you need is:
((TransferCallback)pEndpoint->transfer.fCallback)
Regarding the title to the OP: how to call a function by pointer in C
+1 to Alex's answer of your question about How, but there is another point that can be made in the interest of knowing Why choose a function pointer over just providing the normal function name in the first place; Function pointers are especially useful in C* (see *) when you have a collection of functions that are similar in that they contain the same argument list, but have different outputs. You can define an array of function pointers, making it easier, for example, to call the functions in that family from a switch, or a loop, or when creating a series of threads in a pool that include similar worker functions as arguments. Calling an array makes it as simple as changing the index of the pointer to get the specific functionality you need for each unique case.
As a simple example, the two string functions strcat() and strcpy() have the argument list: (char *, const char *), therefore, may be assigned to an array of function pointers. First create the function pointer array:
char * (*pStr[2])( char *a, const char *b);` //array of function pointers pStr[]
Then, make the assignements of strcat and strcpy to the array:
void someFunc(void)
{
pStr[0] = strcat; //assign strcat to pointer [0]
pStr[1] = strcpy; //assign strcpy to pointer [1]
}
Now, strcat() or strcpy() can be called as:
int main(void)
{
char a[100]="kjdhlfjgls";
char b[100]="kjdhlfjgls";
someFunc();//define function pointers
pStr[0](a, "aaaaaaaa"); //strcat
pStr[1](b, "aaaaaaaa"); //strcpy
return 0;
}
Example output:
This is just a simple example. It does not explore the full extent of usefulness function pointers can provide, but illustrates another reason why functions pointers may be preferred in some situations.
* This illustration is targeted only to C, as opposed to C++, where qualities of inheritance and polymorphism inherent to that language would make this suggestion unnecessary.
if I have a structure that has a pointer to a function like this
struct str{
int some_element;
char other_element;
int (*my_pointer_to_a_function)(int);
};
struct str my_struct;
int my_function(int);
and I asign values to it
my_struct.some_element = 1;
my_struct.other_element = 'a';
my_struct.my_pointer_to_a_function = my_function;
how do I call the function that the pointer is pointing to (using the pointer)?
My initial guess is this:
my_struct.(*my_pointer_to_a_function)(value);
or should it be
*my_struct.my_pointer_to_a_function(value);
?
Thank you.
Pointers to functions can be used as-is, without any dereference:
my_struct.my_pointer_to_a_function(value)
But if you insist in dereferencing it you have to use parenthesis this way:
(*my_struct.my_pointer_to_a_function)(value)
They both are totally equivalent, so I recommend the first one, that is simpler.
About you first try:
my_struct.(*my_pointer_to_a_function)(value); //Error!
That won't work because the expression in parenthersis has to be evaluated first: *my_pointer_to_a_function, but that alone means nothing.
And your second:
*my_struct.my_pointer_to_a_function(value); //Error!
The operator precedence rules evaluates first the ., then the function call, and lastly the *:
*(my_struct.my_pointer_to_a_function(value)); //Error!
So the function would be called, but the result of the call, an int, would be dereferenced, hence the error.
Suppose you have pointer to function as you struct member like:
struct newtype{
int a;
char c;
int (*f)(struct newtype*);
} var;
int fun(struct newtype* v){
return v->a;
}
You can call it as follows:
int main(){
var.f=fun;
var.f(&var);
// ^.....^..... have to pass `var` as an argument to f() :( :(
}
//Comment: here in var.f(&var); I miss this pointer and C++,
So for your case it should be just my_struct.my_pointer_to_a_function(value);
Additionally points:
Important to note in my example even you wants to access members of same structure variable you have to pass that. (its quite dissimilar than c++ object!)
virtual functions in C++ classes. They are implemented in a similar fashion under the hood.
Here is a project that will help you to use: Function pointers inside structures
Use this:
#define function mystruct.my_pointer_to_a_function
Then you can call the function :
int i = function(value);