2012-07-20 65 views
0

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

所以,我有2个文件,这使得静态库: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 <keyboard_input.h> 
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()的定义,它就起作用了。

但有件事情我不明白,当我键入:让keyboardReader这里是输出:

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

有什么错吗?音符错误消息是否使我的lib省略了keyboard_input.c文件?

回答

3

你在混合使用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++内部名称(它对签名中的所有类型信息进行编码,这就是链接器区分重载函数的原因),然后链接器找不到它。

+0

图标和按钮没有显示出来,我不确定它是否已将您的答案标记为已接受。但是谢谢。我放心,终于知道了这个extern {}部分的目的。 – Salepate 2012-07-20 13:55:32