我不是Linux的常客,我想我做错了什么。
这是我正在生成的测试动态库“.so”的代码。
class InternalClass
{
public:
int Function(){ return 10; }
};
extern "C"
{
int WrapperFunctionSimple() { return 10; }
void WrapperCreateInstance() {InternalClass* item = new InternalClass(); delete item; }
}
编译失败,并出现以下错误:
g++ -Wall -fexceptions -O2 -c /home/lidia/compartida/TestLibrary/TestLibrary/main.cpp -o obj/Release/main.o
g++ -shared obj/Release/main.o -o bin/Release/libTestLibrary.so -s
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: obj/Release/main.o: warning: relocation against `_Znwm@@GLIBCXX_3.4' in read-only section `.text'
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: obj/Release/main.o: relocation R_X86_64_PC32 against symbol `_Znwm@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
我按照建议尝试使用-fPIC,它可以编译。但是当使用这个库时,当我添加最后一个函数时,它不能被加载:
void WrapperCreateInstance() {InternalClass* item = new InternalClass(); delete item; }
问题是使用InternalClass,没有这个函数一切都正常。
我用的是VirtualBox。我安装了64位的OpenSUSE,使用这个库的应用程序也是64位的。在另一个linux发行版(Mint)中,使用完全相同的项目和设置(没有fPIC),它可以被编译。当我使用那个库(.so)时,它在SUSE中工作。
我还使用:
- gcc(SUSE Linux)7.5.0版
- g++(SUSE Linux)7.5.0版中的一个版本
- 我的IDE是Code::Blocks 20(最新版本)。除了-m64标志外,其他设置均为空。
我做错了什么?这似乎是高级Linux用户可以帮助我理解的东西。
编辑:要添加更多信息,可以使用相同的设置在Ubuntu中编译。
4条答案
按热度按时间nbysray51#
对我来说,如果一个库(A)依赖于另一个库(B),并且库A在库B之前被链接,那么这种情况就发生了。解决方案是先链接库B,然后链接库A。
x6492ojm2#
当我使用GCC编译CPP文件时,我也遇到过这种情况。因此,对于C文件,只使用g,而显然不使用GCC,因为GCC是针对C文件的。
fdx2calv3#
我在ubuntu中使用cmake和GCC,我得到了同样的错误。
在我的例子中,我添加了XX. h文件来包含目录,并在main.cpp中使用了一个在XX. h头文件中定义的“typedef struct x”。
当我在Cmake的add_executable()中将XX. c添加到目标可执行源代码时,这个错误被清除。
我希望我能清楚地陈述我的情况。
de90aj5v4#
在我的例子中,当我有一个抽象类A和两个派生类B和C时,就发生了这种情况,如下所示。
但是其中一个派生类(此处为
class B
)只有doNothing()
的声明,但在项目文件中的任何位置都缺少定义。