问题描述
在写代码的时候,将一个matlab算法转化为c++ 格式,测试完成运行时间之后,打算打成动态库,直接修改了编译链接参数宏,发现不能够运行编译成的程序了。
解决方式
修改编译链接参数宏,将-shared 或 -fPIC选项从编译程序时去掉,只在动态库生成时使用。
思考
为什么-shared 或 -fPIC这两个参数会产生这样的影响?原因是什么?它在编译链接时干了什么事情?
-shared 和 -fPIC 都是 GCC 编译器的选项,它们通常用于生成动态链接库。
-shared 选项告诉编译器生成一个共享对象,可以链接到其他对象中。这通常用于创建动态链接库。
-fPIC 选项告诉编译器生成位置无关代码(Position Independent Code)。这意味着生成的代码可以在内存中的任何位置执行,这对于动态链接库是必要的,因为你无法预先知道代码将在内存中的哪个位置执行。
然而,如果你的目标不是创建一个动态链接库,而是一个可执行文件,那么 -shared 和 -fPIC 选项可能会导致问题。这是因为这些选项会改变编译器生成代码的方式,可能会导致生成的代码无法正确执行。
在我的情况下,由于我的目标是生成一个可执行文件,而不是一个动态链接库,所以去掉 -shared 和 -fPIC 选项后问题就解决了。
在编译过程中,编译器会将源代码转换为机器代码,这个过程中会涉及到很多的细节,其中一部分就是如何处理内存地址。这就是 -shared 和 -fPIC 选项涉及到的内容。
1.-shared 选项:这个选项告诉编译器生成的是一个动态库,也就是说,这个库在编译的时候并不知道它将会被加载到内存的什么位置,因此,它生成的代码需要能够在被加载到内存的任何位置后都能正确运行。这就需要编译器生成一种特殊的代码,这种代码在引用内存地址时,不是直接引用具体的地址,而是使用相对于当前代码位置的偏移量来引用。这样,无论代码被加载到内存的什么位置,这些引用都能正确工作。
2.-fPIC 选项:这个选项告诉编译器生成位置无关代码(Position Independent Code)。这种代码同样可以在内存的任何位置执行,因为它使用的是相对地址而不是绝对地址。这对于动态库是必要的,因为动态库在被加载时,其在内存中的位置是不确定的。
然而,如果你的目标是生成一个可执行文件,那么情况就不同了。可执行文件在被加载到内存时,其位置是由操作系统决定的,而且一旦确定就不会改变。因此,可执行文件中的代码可以直接使用绝对地址,而不需要使用相对地址。这样可以简化代码,提高执行效率。
如果你在编译可执行文件时使用了 -shared 或 -fPIC 选项,那么编译器会生成适用于动态库的代码,这种代码在执行时需要额外的步骤来处理地址引用,这可能会导致效率降低,甚至在某些情况下无法正确执行。这就是为什么在编译可执行文件时,不应该使用 -shared 和 -fPIC 选项的原因。
分享一个有趣的 学习链接:https://xxetb.xet.tech/s/HY8za