意外的未定义引用

我得到一个未定义的引用错误,不知道原因。

所以我有两个文件构成一个静态的lib:keyboard_input.c,keyboard_input.h

这是.h文件的内容:

#ifndef __MOD_KBINPUT__ #define __MOD_KBINPUT__ int kbInit(); int kbWait(); int kbTest(); #endif 

并且CMakeLists.txt文件如下所示:

 FILE( GLOB_RECURSE sources *.c ) INCLUDE_DIRECTORIES("${PROJECT_SOURCE_DIR}/include/utils/kbreader") ADD_LIBRARY(keyboardReader ${sources}) 

编译此lib会发出一些警告:

 src/utils/kbreader/keyboard_input.c: In function 'kbInit': src/utils/kbreader/keyboard_input.c:13:14: warning: assignment from incompatible pointer type [enabled by default] src/utils/kbreader/keyboard_input.c: In function 'kbWait': src/utils/kbreader/keyboard_input.c:21:55: warning: passing argument 4 of 'fread' from incompatible pointer type [enabled by default] /usr/include/stdio.h:708:15: note: expected 'struct FILE * __restrict__' but argument is of type 'struct FILE *' 

现在,对于我的主要可执行文件(main.cpp):

 #include  int main() { kbTest(); return 0; } 

由以下CMakeLists.txt文件处理:

 include_directories("${PROJECT_SOURCE_DIR}/include/utils/kbreader") file( GLOB_RECURSE srcs *.cpp ) add_executable( PEM ${srcs} ) target_link_libraries(PEM keyboardReader) 

最终得到错误:

 CMakeFiles/PEM.dir/main.cpp.o: In function `main': main.cpp:(.text+0xb): undefined reference to `kbTest()' collect2: ld returned 1 exit status make[2]: *** [src/PEM/main2/PEM] Error 1 make[1]: *** [src/PEM/main2/CMakeFiles/PEM.dir/all] Error 2 

创建了libkeyboardReader.a,kbTest()函数除了以外什么都不做

 {return 0; } 

如果我在头文件中设置kbTest()的定义,它就可以工作。

但是当我输入时,有一些我无法得到的东西:make keyboardReader在这里是输出:

 [ 73%] Building C object src/utils/kbreader/CMakeFiles/KeyboardReader.dir/keyboard_input.co [Warning explained above] Linking C static library ../../../lib/libKeyboardReader.a 

有什么不对? note错误消息是否使我的lib省略了keyboard_input.c文件?

你正在混合C和C ++文件。 要做到这一点,你只需告诉C ++编译器它正在调用一个C函数,通过更改头文件,如下所示:

 #ifndef MOD_KBINPUT #define MOD_KBINPUT /* note I also fixed the macro so you aren't using a system-reserved name */ #if __cplusplus /* this is the important part */ extern "C" { #endif int kbInit(); int kbWait(); int kbTest(); #if __cplusplus } #endif #endif 

否则,C ++编译器会假定该函数将被赋予一个C ++内部名称(它编码签名中的所有类型信息,这是让链接器区分重载函数)然后链接器找不到它。