【发布时间】:2018-04-14 21:49:27
【问题描述】:
我正在尝试为一个项目编写一个 makefile。该项目涉及一个测试程序,它定义了一个用 C++11 编写的 main 函数,该函数应该调用一个用 c99 编写的共享对象库并运行一些测试。
我的 makefile 成功编译 c99 库并生成“libhanoi.so”。
当我尝试将 C99 库链接到 C++11 部分时,我收到以下错误:
g++ -std=gnu++11 -L. -lhanoi -o main tests/testing.cpp tests/main.cpp
/tmp/cctHQTcW.o: In function `binarion_constructor(unsigned long*)':
main.cpp:(.text+0x28): undefined reference to `binarion64_t'
collect2: error: ld returned 1 exit status
Makefile:29: recipe for target 'tests' failed
make: *** [tests] Error 1
但是,“nm -C libhanoi.so”的输出显示 binarion64_t 函数正在由 libhanoi.so 导出:
0000000000000610 T binarion64_t(long long, long long)
当我在 libhanoi.so 的名称中引入一个错字时,它会引入一个错误,说它找不到 libhanoi.so。
所以它必须能够找到 libhanoi.so 并且 libhanoi.so 正在导出 main.cpp 中未实现的函数,但它仍然给出未定义的引用。怎么回事?
小例子:
hanoi.h:
#ifndef HANOI_H
#define HANOI_H
#include <inttypes.h>
// binarion (base -1+i) constructor
uint64_t binarion64_t(long long A, long long B);
#endif // HANOI_H
binarion.c:
#include "hanoi.h"
uint64_t binarion64_t(long long A,long long B){
return 0;
}
main.cpp:
#include <stdio.h>
extern "C" {
#include "hanoi.h"
};
uint64_t binarion_constructor(uint64_t * args){
return binarion64_t(args[0], args[1]);
}
int main(void){
return 0;
}
编译:
g++ -std=c99 -c binarion.c
g++ -std=c99 -shared -o libhanoi.so binarion.o -lm
g++ -std=gnu++11 -L. -lhanoi -o main main.cpp
输出:
/tmp/ccjoRmCg.o: In function `binarion_constructor(unsigned long*)':
main.cpp:(.text+0x28): undefined reference to `binarion64_t'
collect2: error: ld returned 1 exit status
编辑:
我正在运行的命令是:
gcc -std=c99 -c binarion.c
gcc -std=c99 -shared -o libhanoi.so binarion.o -lm
g++ -std=gnu++11 -L. -lhanoi -o main main.cpp
文件正是问题中的文件。 “readelf -s libhanoi.so | grep binarion”的输出是:
12: 0000000000000660 19 FUNC GLOBAL DEFAULT 11 binarion64_t
33: 0000000000000000 0 FILE LOCAL DEFAULT ABS binarion.c
46: 0000000000000660 19 FUNC GLOBAL DEFAULT 11 binarion64_t
“g++ -std=gnu++11 -L.-lhanoi -o main main.cpp”的输出为:
/tmp/cczfgY8M.o: In function `binarion_constructor(unsigned long*)':
main.cpp:(.text+0x28): undefined reference to `binarion64_t'
collect2: error: ld returned 1 exit status
【问题讨论】:
-
在 C++ 代码中包含 C 标头时,您必须将包含内容包装到
extern "C" { }中。否则函数名称会被破坏。最好把#ifdef __cplusplus\nextern "C" {\n#endif放在标题的开头,#ifdef __cplusplus\n}\n#endif放在底部。 -
我尝试在 extern "C" { } 括号内外包含定义 binarion64_t 的标头和函数声明本身,但没有成功。
-
嗯。然后请提供minimal reproducible example。
-
我无法重现该问题;我的尝试正如我希望/期望的那样奏效。 HolyBlackCat 的建议很好。
-
按要求添加了一个最小示例。
标签: c++ compiler-errors linker