【发布时间】:2017-06-15 20:21:59
【问题描述】:
我在尝试编译和链接一个依赖第三方库的非常简单的应用程序时遇到“未定义引用”错误。
我的 main.c 看起来像这样:
#include "ss7cp.h"
/*
extern "C" {
void EINSS7CpMain_CpInit(void);
}
*/
int main() {
EINSS7CpMain_CpInit();
}
第三方头文件有:
#if defined (__cplusplus) || defined (c_plusplus)
extern "C" {
#endif
...
void EINSS7CpMain_CpInit(void);
这个函数的定义在一个存档中:
$ nm -g /path/to/lib/libsign_64_utr.a | grep EINSS7CpMain_CpInit 0000000000005ae0 T EINSS7CpMain_CpInit U EINSS7CpMain_CpInit U EINSS7CpMain_CpInit通过上面的“T”,该函数必须在存档中某个库的文本/代码部分中定义。
我目前没有使用 Makefile,只是尝试完全从命令行快速构建这个简单的应用程序:
g++ -I/path/to/include -L/path/to/lib -lsign_64_uthr -D__EXTENSIONS__ -DLINUX main.c(文档告诉我同时定义__EXTENSIONS__ 和LINUX)。上面的其余部分非常简单。我得到的是:
我已经尝试过作为 C 文件 (main.c) 和 C++ 文件 (main.cpp,启用 extern "C" 块),但没有区别。 (我可以假设 g++ 仅通过文件扩展名来决定 C 还是 C++?)
我什至刚刚编译了文件(使用-c)并查看了生成的 main.o 目标文件的内容,并看到了文本“EINSS7CpMain_CpInit”原样,未损坏(或者这可能只是一个调试符号?)
我可以采取哪些诊断步骤来查看我遗漏了什么?我真的需要创建一个 Makefile 并拆分编译和链接步骤吗?
自从我上次做任何 C/C++ 以来已经有很多年了,甚至在我做的时候,我通常不是必须从头开始创建 Makefile 的人,所以我可能在这里遗漏了一些非常基本的东西。 ..
【问题讨论】:
-
“我可以假设 g++ 仅通过文件扩展名来决定 C 还是 C++ 吗?” 不能。
-
nm -u main.o给了我U EINSS7CpMain_CpInit,所以我假设这不仅仅是名称修改问题? -
“我可以采取哪些诊断步骤”
nm告诉您有关链接库中的符号的哪些信息? -
@πάνταῥεῖ 感谢指点!