0

First of all, I'm not sure if the title describes well the problem, feel free to change or suggest a more fitting heading.

I have the following problem: I need to pass a function pointer to some struct. When I define the function in the same file, this works perfectly fine. See here:

static void a_func(int param1, /*...*/) {
    //...
}

static const struct bt_mesh_handlers my_handlers = {
    .set = a_func,
    // ...
};

When I now define this function in another file, I can't get it to work: the header file (include guards are not shown here):

//function declaration:
void a_func(int param1, /*...*/);

the c file:

//function definition (this was defined wrongly as static before)
void a_func(int param1, /*...*/) {
    //...
}

in the main-file:

#include "myheader.h"

static const struct bt_mesh_handlers my_handlers = {
    .set = a_func,
    // ...
};

When I outsource my function to another file, I get the following error during build:

undefined reference to `a_func'

I already did some research and I'm relatively sure that in the file where a_func is defined, there automatically is generated a function pointer with the same name. Consequently, I can use that pointer to hand over my function to the struct.

But I don't know how to get that function pointer from the outsourced file into my main file. What would a good solution look like?

1
  • Thanks for your tips, you are absolutely right. I fixed this in my question now Commented May 21, 2023 at 18:24

3 Answers 3

1

Remove static from the declarations of a_func, including its definition.

In this context, static gives the identifier a_func internal linkage, meaning uses of the name will only be linked to a definition of the name in the same translation unit (the source file being compiled, including all files it includes directly or indirectly).

To link to a name defined in another translation unit, you want external linkage. That is the default for functions, so removing static will give you external linkage.

I already did some research and I'm relatively sure that in the file where a_func is defined, there automatically is generated a function pointer with the same name.

The name of a function refers to the function. It designates the function. In C, a function designator is automatically converted to a pointer to the function, except when it is the operand of sizeof or unary &. There is no special or separate “generation” of a function pointer with the same name as the function in the file where it is defined. The compiler, linker, and/or program loader work together to know where the function is and to generate appropriate instructions to use the function or to provide its address.

Sign up to request clarification or add additional context in comments.

5 Comments

As already stated in my other questions, I put the static here by mistake (when I tested I didn't use it). Unfortunately, it is still not building. Thanks a lot for the great explanation of the designator being converted to a pointer, that already explained a lot. But as I assume now, this designator/pointer only seems to be seen in the file itself, not by files that include the header file. So is there a way to make it visible for outer files as well? Or where else could be the issue? My file is still not building, I get the same error :/
@Sespaetzlean: Show the exact error message and the command used to link the program.
I'm building with nRF Connect. The command should be sth like: west build ... . (I just hit the build button in VS code in the nRF connect extension) I get the following error: d:/ncs/toolchains/v2.3.0/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.1.0/../../../../arm-zephyr-eabi/bin/ld.exe: app/libapp.a(model_handler.c.obj):(.rodata.lvl_handlers+0x0): undefined reference to `a_func'
You will need to dig the actual link command out of the build log or figure out what in your build settings is wrong. A likely cause is that your project is not linking all the object modules together into one program.
I did some research and my files have not been linked properly. Thx for the help, I thought it was a visibility issue :)
1

A static function shall be defined in each translation unit where it is used because it has internal linkage. So in the translation unit with main in your example the function is not defined,

Either define it in the header (you can define it for example as an inline function) or remove the storage class specifier static to make the function with external linkage.

2 Comments

Not an answer for the original question.
Thank you for your help. You are right, I put the static keyword by mistake here in my question (and now fixed in the question :) )
0

To sum it up: The issue was that my files had not been linked properly. It is possible to call a function from a different file AND to use its pointer (that did not work for me in the beginning). Eric explained well how this works via a designator.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.