C++ Can';t将C共享对象链接到C++;程序

C++ Can';t将C共享对象链接到C++;程序,c++,compiler-errors,linker,C++,Compiler Errors,Linker,我正在尝试为一个项目编写一个makefile。该项目涉及一个测试程序,该程序定义了一个用C++11编写的主函数,该函数应该调用用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 `b

我正在尝试为一个项目编写一个makefile。该项目涉及一个测试程序,该程序定义了一个用C++11编写的主函数,该函数应该调用用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”的输出显示libhanoi.so正在导出binarion64_t函数:

0000000000000610 T binarion64_t(long long, long long)
当我在libhanoi.so的名称中输入一个拼写错误时,它会引入一个错误,表示找不到libhanoi.so

因此,它必须能够找到libhanoi.So和libhanoi.So正在导出main.cpp中未实现的函数,但它仍然提供未定义的引用。发生什么事了

最简单的例子:

河内:

#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
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;
}
输出:

/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”的输出为:

“g++-std=gnu++11-L.-lhanoi-o main.cpp”的输出为:

TL;博士:

使用:


说明:

你应该使用<代码> gcc>代码>编译一个C文件,<代码> g++< /Cord>是C++的。当您执行
g++-std=c99-c binarion.c
时,编译器会提示您:

cc1plus: warning: command line option ‘-std=c99’ is valid for C/ObjC but not for C++
<>这意味着你最终编译你的库作为C++库。您可以通过调用
readelf-s libhanoi.so | grep binarion
来验证:

 9: 00000000000005da    19 FUNC    GLOBAL DEFAULT    9 _Z12binarion64_txx
29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS binarion.c
44: 00000000000005da    19 FUNC    GLOBAL DEFAULT    9 _Z12binarion64_txx

正如你所看到的,函数已经被名称化,这是C++所做的,而C没有。 但是,在编译

main.cpp
时,您会告诉编译器
binarion\u t
具有C链接:

extern "C" {
#include "hanoi.h"
};

<> >搜索未加密的代码> BialNoNo.T/<代码>(而不是<代码>,Z12BiaRiNoNo.64,txx < /C> >)

当在C++代码中包含C头时,必须将包括到 Extn(c){} /Cuth>中。否则,函数名将被损坏。最好将
#ifdef_ucplusplus
\n
extern“C”{
\n
#endif
放在头的开头,将
#ifdef_uucplusplus
\n
\n
#endif
放在底部。我已经尝试将定义二进制数的头和函数声明本身包含在extern“C”的内部和外部没有成功。然后请提供一个答案。我无法重现这个问题;我的尝试如我所希望的那样奏效了。HolyBlackCat的建议很好。根据要求添加了一个最小的示例。此解决方案没有完全起作用。运行这些命令后,“readelf-s libhanoi.so | grep binarion”的输出显示了未混合的名称,但我仍然得到相同的未定义引用错误。(这与问题中的设置完全一致。)@firstnamegklsodascb那么您可能没有编译与此处发布的文件相同的文件,或者编译器有问题。你能用你使用的确切文件、编译它们的确切命令以及
readelf-s libhanoi.so | grep binarion
的输出来更新你的问题吗?
/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
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
cc1plus: warning: command line option ‘-std=c99’ is valid for C/ObjC but not for C++
 9: 00000000000005da    19 FUNC    GLOBAL DEFAULT    9 _Z12binarion64_txx
29: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS binarion.c
44: 00000000000005da    19 FUNC    GLOBAL DEFAULT    9 _Z12binarion64_txx
extern "C" {
#include "hanoi.h"
};