简体   繁体   English

如何修复C ++“对...的未定义引用” C函数指针?

[英]How to fix C++ “Undefined reference to …” C function pointer?

I am trying to call a function (from an #included library) that takes as a parameter a function pointer, and passing to this function a pointer to a function located in a C file. 我试图调用一个函数(从#included库中),该函数将函数指针作为参数,并将指向C文件中函数的指针传递给该函数。 The compiler throws an "undefined reference to [function name]" error. 编译器将引发“对[函数名]的未定义引用”错误。

I tried removing the code from the .c file and putting it directly into main.cpp file (see below the section marked 'THIS WORKS') - and the error is avoided. 我尝试从.c文件中删除代码,然后将其直接放入main.cpp文件中(请参见下面标记为“ THIS WORKS”的部分)-并避免了该错误。 I know that I should be able to keep it in the .c file because I am following very closely to an example that compiles without errors. 我知道我应该能够将其保存在.c文件中,因为我非常关注一个无错误编译的示例。

/****************/
/*** MAIN.CPP ***/
/****************/

extern "C"
{
    #include "btntask.h"
}

using namespace touchgfx;

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

#define configGUI_TASK_PRIORITY                 ( tskIDLE_PRIORITY + 3 )
#define configGUI_TASK_STK_SIZE                 ( 1024 )

static void GUITask(void* params)
{
    /* STUFF */
}


/*********** THIS WORKS ************/

/*
void btn_tasked(void* params)/{
    /* STUFF */
}
*/

/*********** THIS WORKS ************/


int main(void)
{
    xTaskCreate(GUITask, "GUITask",
                configGUI_TASK_STK_SIZE,
                NULL,
                configGUI_TASK_PRIORITY,
                NULL);

    /* error undefined reference to btn_task */
    xTaskCreate(btn_task, "BTNTask",
               512,
               NULL,
               configGUI_TASK_PRIORITY+1,
               NULL);

    for (;;);
}

This is btntask.h 这是btntask.h

/****************/
/*** btntask.h ***/
/****************/
#ifndef BTNTASK_H
#define BTNTASK_H

    void btn_task(void* params);

#endif /* BTNTASK_H */

This is btntask.c 这是btntask.c

/****************/
/*** btntask.c ***/
/****************/

#include "btntask.h"

void btn_task(void* params)
{
  /* STUFF */
}

The compiler log is as follows: 编译器日志如下:

Converting images
Compiling Core/Src/main.cpp
Linking TouchGFX/build/bin/target.elf
TouchGFX/build/ST/STM32F429IDISCO/Core/Src/main.o: In function `main':
d:\Dropbox\TouchGFXProjects\MiniGame\Project/Core/Src/main.cpp:116: undefined reference to `btn_task'
collect2.exe: error: ld returned 1 exit status
gcc/Makefile:363: recipe for target 'TouchGFX/build/bin/target.elf' failed
make[2]: *** [TouchGFX/build/bin/target.elf] Error 1
gcc/Makefile:359: recipe for target 'generate_assets' failed
make[1]: *** [generate_assets] Error 2
../gcc/Makefile:45: recipe for target 'all' failed
make: *** [all] Error 2

The compilation is performed by the software package I am using (TouchGFX). 编译由我正在使用的软件包(TouchGFX)执行。 If it is helpful, this is the compilation commands reported in the log: 如果有帮助,请在日志中报告以下编译命令:

touchgfx update_project --project-file=simulator/msvs/Application.vcxproj && touchgfx update_project --project-file=../EWARM/application.ewp && touchgfx update_project --project-file=../EWARM6/project.ewp && touchgfx update_project --project-file=../MDK-ARM/application.uvproj

make -f ../gcc/Makefile -j8

* UPDATE * I noticed that TouchGFX populates a Debug folder of .obj files, one for each of the source code files in the application, and I can see that it is missing a btntask.obj. *更新*我注意到TouchGFX填充了一个.obj文件的Debug文件夹,该文件夹用于应用程序中的每个源代码文件,我可以看到它缺少btntask.obj。 Clearly it is not linking the btntask.obj file. 显然,它没有链接btntask.obj文件。 I need to figure out why that is. 我需要弄清楚为什么。 There is a makefile that details all of the linking, but it uses a lot of syntax I am not familiar with. 有一个makefile详细介绍了所有链接,但是它使用了许多我不熟悉的语法。

* SOLUTION * Turns out that the Makefile names a list of directories to include. *解决方案*事实证明Makefile列出了要包括的目录列表。 The solution was to edit the list to add additional directories where my btntask files are located. 解决方法是编辑列表,以添加我的btntask文件所在的其他目录。

# Directories containing application-specific source and header files.
# Additional components can be added to this list. make will look for
# source files recursively in comp_name/src and setup an include directive
# for comp_name/include.
components := TouchGFX/gui target TouchGFX/generated/gui_generated

Thanks everyone for chiming in. 谢谢大家的参与。

You need to be aware these two concepts: 您需要注意以下两个概念:

Name Mangling 改名

You may need to wrap btn_task inside extern "C" in your btntask.c file, as well as in your header file. 您可能需要将btn_task包裹在btntask.c文件以及头文件的extern "C"中。

As your project contains C++ file, your C file might be compiled by C++ compiler, not C compiler. 由于您的项目包含C ++文件,因此您的C文件可能由C ++编译器而不是C编译器编译。 Then your C function implementation is name-mangled. 然后,将对C函数实现进行名称拼凑。 But the referring position is still using the non-mangled name. 但是引用位置仍然使用非修改名称。

Link 链接

Don't forget to include product of btntask.c in link stage. 不要忘记在链接阶段包含btntask.c产品。

After all, I'm not familiar with your project controlling software, you have to ensure those two points by yourself. 毕竟,我对您的项目控制软件不熟悉,您必须自己确保这两点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM