multiple definition and making sure function is correctly written - c

This is my .h file
#ifndef _test_h_
#define _test_h_
void new_cmd(void);
void open_cmd(void);
void close_cmd(void);
void close_all_cmd(void);
void save_cmd(void);
void save_as_cmd(void);
void save_all_cmd(void);
void print_cmd(void);
void exit_cmd(void);
void call(char *cmd_name);
struct {
char *cmd_name;
void (*cmd_pointer)(void);
} file_cmd[] =
{
{"new", new_cmd},
{"open", open_cmd},
{"close", close_cmd},
{"save", save_cmd},
{"save as", save_as_cmd},
{"save all", save_all_cmd},
{"print", print_cmd},
{"exit", exit_cmd}};
#endif
This is my function file
void call(char *cmd_name){
int i;
scanf("Enter command: %c\n",cmd_name);
for(i = 0; i < sizeof(file_cmd); i++){
if(strcmp(cmd_name, file_cmd[i].cmd_name) == 0){
file_cmd[i].cmd_pointer();
}
}
I just deleted all file_cmd functions because it seems for other people
and this is my main file
#include <stdio.h>
#include <string.h>
#include "test.h"
int main(void){
char cmd;
call(cmd);
return 0;
}
More I want to know is that my function void call is correctly written.
when I try to compile, it says
expected 'char*' but argument is of type 'char'
multiple definition of 'file_cmd'
first define here.
I am so confused how to fix it.
Please help
thank you.

You have two very different errors that you really should have asked about in two different question, but I'll be nice and answer both anyway.
In the main function you have a variable named cmd. It is of type char. You pass it to the call function, which expects an argument of type char * (i.e. a null-terminated string).
To fix this you first need to make sure that cmd is the correct type (i.e. char * instead of plain char). Secondly you need to make sure this pointer is actually pointing to a valid null-terminated byte string.
In other words, something like this:
char *cmd = "open";
call(cmd);
C really only cares about translation units. A translation unit is a single source files with all included header files.
The problem here is that variables can only be defined in a single translation unit. And since you define the variable file_cmd in a header file that is included in multiple source files, it will be defined in both translation units created from those two source files.
The solution here is to only declare the variable in the header file, and define it in a single source file.
For example, do something like this in the header file
struct command_struct
{
char *cmd_name;
void (*cmd_pointer)(void);
};
extern struct command_struct file_cmd[];
Then in one source file (like your "function file")
struct command_struct file_cmd[] = {
// Your initialization...
};
There are also other problems with your code, some of them will lead to undefined behavior.
For example the sizeof operator returns the size in bytes, not the number of elements in an array. To get the number of elements in an array you need to divide the byte-size of the full array with the byte-size of a single element. For example sizeof file_cmd / file_cmd[0].
Do note that the division only works for real arrays, not pointers, and that arrays very easily decays to pointers (to their first element).

Related

How to obtain the function name and number of arguments from a function in C?

Lets say I am maintaining an array of function structures in which I store API information.
This is definition of function structure:
typedef struct function {
void (*func)(long, ...);
char* name;
int argc;
char *argv[];
} function;
function api_list[N]
I would maintain a list of such structures.
Now given any function, I want to write a function Register(api_list, fp)
which adds one such structure initialized with details of function fp.
int fp(int a, int b) {
return a+b;
}
Register(api_list, fp);
How to do it in C?
I believe you will need to either parse the C function declarations yourself or find some other code to do it. I looked around a bit and there's code for this in the Ruby FFI, PerlXS and other script binding generators like SWIG. I also saw the XML plugin to GCC which generates XML describing the program.
If you look up C's BNF or EBNF definitions and know a bit of parsing theory, figuring out C functions is not hard. C++ is a whole other ball o' wax.
Note: I think I misunderstood. The following is for calling C functions with unknown number and types of arguments. Not for finding out what the function signature already looks like.
Look at the FFI (Foreign Function Interface) library which can be found at Sourceware:
https://sourceware.org/libffi/
This is packaged with many Linux systems already because it is heavily used by interpreted languages that need to call C functions.
Now given any function, I want to write a function Register(api_list, fp) which adds one such structure initialized with details of function fp.
There is no way to do this in Standard C. The main reason is you need keep track of original definition of an function to call it via such structure. You actually could store every function pointer as struct member:
void (*func)()
that is fine, but any attempt to call such function when type is not compatible (both parameters and return type are not the same) with original definition will invoke undefined behaviour. This means, that you would need to cast it properly for every call:
((int (*)(int, int)) api_list[0])(1, 2);
You may use GCC extensions typeof, but this method requires writing function's name (here fp) explicitely:
int result = ( (typeof(fp)*) api_list[0].func)(1, 2);
Even if you have stored somehow character string "fp" inside name member, there is no way to "connect" it with typeof, since it does not take string literals (well it takes, but not in the way you want) and in general there is no way to have it "destringized" as fp token.
Here is an illustration of above concepts:
#include <stdio.h>
typedef void (*GENERIC_FUNC_PTR)();
typedef struct function
{
GENERIC_FUNC_PTR func;
} function;
void Register(function *api_list, GENERIC_FUNC_PTR func)
{
api_list->func = func;
}
int add(int a, int b)
{
return a + b;
}
void print_message(void)
{
printf("%s\n", __func__);
}
int main(void)
{
function api_list[10];
Register(api_list, (GENERIC_FUNC_PTR) add);
Register(api_list + 1, (GENERIC_FUNC_PTR) print_message);
printf("%d\n", ( (typeof(add)*) api_list[0].func)(1, 2));
( (typeof(print_message)*) api_list[1].func)();
return 0;
}

C2055 error - expected formal parameter list, not a type list

I keep getting this error:
C2055 error - expected formal parameter list, not a type list
I know what it means; I read about it on the Internet, yet I don't understand why I keep getting it. The part of my code that triggers the error (the file is called other_funcs.c):
#include "main_funcs.h"
#include "other_funcs.h"
void addWord(sWord **first) //line #4
{
sWord *after;
char *input_string, *part;
const char seperator[4] = "_#_";
/.......bla bla.... more code.../
sWord is a struct. The error is:
1>d:\cs - exercises\ex5\backup\new folder\other_funcs.c(4): error C2055: expected formal parameter list, not a type list
I don't know if this is necessary, but the header file with the the addWord() function is called other_funcs.h:
#ifndef OTHER_FUNCS_H
#define OTHER_FUNCS_H
void addWord(sWord**);
char *inputString();
int badInput(char*);
void removeWord(sWord**);
int checkYear(sWord*, unsigned short);
int my_strlen(char*);
int countDist(char*, char*);
int new_alreadyThere(sWord*, char*)
#endif
When you get a truly weird compiler error, look at the preceding line.
In this case (ignoring whitespace and preprocessor directives), it's this, from the header file.
int new_alreadyThere(sWord*, char*)
You're missing a semicolon at the end of it.
You're missing a semicolon on the last line of the header file.
This confuses the compiler when it tries to parse the next line.

how to call a function by pointer in C

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.

C Function Pointers - What happens when you drop an argument?

all. I'm currently working with an old established code base for a new project which is basically undocumented (i.e. averages 1 one-line comment per file). I just ran into something which I haven't seen before and am not quite sure how to interpret.
Firstly, they define a function type and a function in the header file (.h) in the form:
typedef void (*SOME_FUNCTION)(void *data, EXECUTION_CONTEXT *ec);
void add_function(SOME_FUNCTION aFunction, void *data);
In the main source file (.c), there is a function defined:
void add_function(void (*f)(void *data), void *data)
{
(Some code here)
}
So okay, there's a function pointer... but what the heck happened to the second argument, ec? Why would someone use a code design like this? For reference, when the function add_function is used, it is used in this sort of form:
void passedFunction(void *data, EXECUTION_CONTEXT *ec)
{
(Stuff the function does.)
}
void CallingFunction()
{
data = (some data stuff);
add_function((SOME_FUNCTION)passedFunction, data);
}
So, as you can see, the passed functions use the correct form that fits the original SOME_FUNCTION argument signature, but the definition for the add_function arguments is short by one argument.
Formally, the results are undefined: you are only permitted to call a function via a function pointer if the types match.
As for what actually happens, it depends on the calling convention and what the function does with the arguments. Chances are, the results aren't going to be good.
To add on James' answer:
Since the default calling convention is most likely cdecl, the call site is responsible for cleaning up the stack after passedFunction returns. Since the call site knows that it passed just 1 argument to the callee, the compiler can clean up the stack normally (even though technically this is undefined behavior).
Change the calling convention on passedFunction to stdcall though, and you 're in for some fireworks.
From the example code below, it doesn't appear that the variable(s) that are defined in the function pointer matters during the check. The code below compiles without warning.
#include <stdio.h>
int temp(int (*m)());
int main(int argc, char *argv[]) {
return temp(main);
}
int temp(int (*m)()) {
return 1;
}
However, the code below throws an error.
#include <stdio.h>
int temp(void (*m)());
int main(int argc, char *argv[]) {
return temp(main);
}
int temp(void (*m)()) {
return 1;
}
Due to this; it seems that the compiler (at least in my case GCC) only cares what the return value of the function pointer will be. The interesting thing here is that you CAN send the parameters correctly but if you do NOT specify the parameter (in our example m()), then the variables in m() when called will be junk.

Passing function pointers & int references to another function

Just started working on a c project. Need help with passing function pointers/macro functions/etc. I'm a php & python OO guy, but new to c. I tried to generalize the example for this post. I have a main.c with a lib for the Axon microcontroller I'm working with. Works like a charm with everything in main.c. I need to move some of the functionality out of main to more organized lib files as my code grows. The base microcontroller lib creates a macro function that allows me to send data to the microcontroller to make a servo move left or right. I now need to create a servo specific file (HS-422.c) that will will allow me to pass references/pointers(?) to a generic function that will execute for each servo to ease on code duplication.
Keep in mind I'm only focused on passing macros/functions/variable references to other functions and have them called / set. The other basics of c I understand. I must have tried a 100 different ways to make this work today with no luck. So just wrote a simplified version hoping you might get an idea of what I'm attempting.
Thank you for your help!
/*
* main.h
* I'm trying to make a pointer or reference to the macro.
* The original file had:
* #define servo1(position) servo(PORTE,2,position);
*/
// servo is a macro defined in another microcontroller file
#define (void)(*servo1)(position) servo(PORTE,2,position);
#define (void)(*servo2)(position) servo(PORTE,3,position);
/* main.c */
// init main functions
void servo_scan(void);
// init vars
int servo1_location = 0;
int servo2_location = 0;
int main(void)
{
for(;;)
{
servo_turn();
}
}
// get the servos to turn
void servo_turn(void)
{
turn_servo( *servo1, &servo1_location, 200);
turn_servo( *servo2, &servo2_location, 950);
}
/* HS-422.c */
void turn_servo(void (*servo)(int position), int &currentLocation, int newLocation)
{
// turning
for(uint16_t i=&currentLocation; i<newLocation; i=i+10)
{
// turn servo
// hoping the specifc passed servo# pointer gets called
*servo(i);
// set value by reference to origional servo#_location var. making sure.
&currentLocation = i;
// pause
delay_ms(20);
}
}
It's not really clear to me exactly what you're trying to achieve, but what is clear is that you don't really understand the concept of pointers/references in C - so I'll try to clarify, and hopefully that will help you implement what you need.
Firstly, there is no such thing as a "reference" in C. The only alternative to passing by value is to pass a pointer. A pointer is basically just a memory address, and you can get a pointer (memory address) to a variable using the & (address of) operator. When passing a pointer variable to a function, you do something like the following:
Given a function which takes a pointer:
int foo(int* pointer);
You would pass the memory address of an int variable to this function like so:
int x = 10;
foo(&x);
So right off the bat, you can see that your function definition above is wrong:
void turn_servo(void (*servo)(int position), int &currentLocation, int newLocation);
This is simply a syntax error. It will not compile because of the int &currentLocation. The & operator is used to take the address of a variable. It can't be used in a function parameter. If you want a "reference" to currentLocation, you need to pass in a pointer, so your function parameters should be written as:
void turn_servo(void (*servo)(int position), int* currentLocation, int newLocation);
Secondly, when you want to modify the value pointed to by the currentLocation pointer, you need to use the * operator to dereference the pointer. So, the line where you set currentLocation is not correct. What you want to say is:
// set value by to origional servo#_location var. making sure.
*currentLocation = i;
And of course, the line:
for(uint16_t i=&currentLocation; i<newLocation; i=i+10)
should be:
for(uint16_t i= *currentLocation; i<newLocation; i=i+10)
Note that in your original code you use the & operator in both cases, which takes the address of a variable. Since currentLocation is already a memory address, this would result in taking the address of an address, also known as a pointer-to-a-pointer, which is certainly not what you want here.
Finally, the phrase "pointer or reference to the macro" is completely nonsensical. A macro is not a function. It is more like a meta-function: essentially it is a template used by the C preprocessor to generate further source code. The C preprocessor is invoked before the compilation phase, and basically acts as a find/replace mechanism in the source code. You can't have a pointer to a macro, because for all intents and purposes macros don't even exist in the compilation phase. They are only meaningful to the preprocessor.
There may be more here, but ultimately you seem to have a fundamental misunderstanding of pointers (as well as macros) in C, and short of providing a complete tutorial, the best I can do is point out the syntax problems. I highly recommend you read a good introductory book to C, which will certainly go over pointers, macros, and functions.
I have picked the main point of your code and have this code below.
You may want to modify your #define in your original code.
Please see the code below: (you can also run this)
void myFunc(int pos);
void myFunc2(int pos);
int main (int argc, const char * argv[]) {
typedef void (*pFunc)(int);
pFunc pfArr[2];
pfArr[0] = &myFunc;
pfArr[1] = &myFunc2;
int x = 3;
int newLoc = 4;
turn_servo(pfArr[1], x, newLoc);
turn_servo(pfArr[0], x, newLoc);
return 0;
}
void turn_servo(void (*servo)(int position), int currentLocation, int newLocation)
{
printf("\nturn_servo starts");
printf("\nturn_servo currentLocation: %d", currentLocation);
printf("\nturn_servo newLocation: %d", newLocation);
servo(1);
}
void myFunc(int pos)
{
printf("\nmyFunc starts");
printf("\nmyFunc pos: %d", pos);
}
void myFunc2(int pos)
{
printf("\nmyFunc2 starts");
printf("\nmyFunc2 pos: %d", pos);
}
Your turn_servo() function will now accept two functions as parameter (either myFunc() or myFunc2()).
Just get the main point of this code and apply it. Hope this will help.

Resources