• 算法小白的心得笔记:分清楚执行程序和动态链接库的编译方式。


    问题描述

    在写代码的时候,将一个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

  • 相关阅读:
    vue3 PC端项目构建TS,vue3+ant+vite+axios+pinia+sass+typescript
    Python程序的5种图像处理特效
    3.机器学习-十大算法之一线性回归算法(LinearRegression)原理讲解
    AtCoder abc140
    tsne可视化cnn模型
    SSM+校园好货APP的设计与实现 毕业设计-附源码121619
    DDD/ABP/EF Core :新特性Owned Entity Types ,尝试另外一种值对象的配置方式
    3.35 OrCAD中怎么产生Cadence Allegro的第一方网表?OrCAD软件输出Cadence Allegro第一方网表报错时应该怎么处理?
    Centos7 升级 Kubernetes(k8s) 集群
    VMware Workstation Pro 12 ubuntu 20.04 突然奔溃,重新打开后导致win11系统蓝屏问题
  • 原文地址:https://blog.csdn.net/qq_29111047/article/details/134256026