zoukankan      html  css  js  c++  java
  • 动态库与静态库

    最近项目中,使用动态库和静态库时,出现了一个问题。在动态库中调用静态库,在编译动态库时,总是无法通过。报错内容如下:

    error:relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

    在静态库中添加了-fPIC,还是无法解决该问题。于是找到了下面这篇文章:

      

    生成动态库: 需要的目标文件得用-fPIC选项生成.

    而静态库所需的目标文件可以不用-fPIC选项.

    例:

    代码如下:

    /////// static.h

    void static_print();

    ///////static.cpp

    #include <iostream>

    #include "static.h"

    void static_print() {

         std::cout<<"This is static_print function"<<std::endl;

    }

    ////// shared.h

    void shared_print();

    ////// shared.cpp

    #include <iostream>

    #include "shared.h"

    #include "static.h"

    void shared_print() {

           std::cout<<"This is shared_print function";

            static_print();

    }

    ////////test.cpp

       #include "share.h"

    int main()
    {
           shared_print();
           return 0;
     }

    方法一:

    静态库的.o文件也用-fPIC生成. 生成动态库时把静态库加入.

     生成应用程序时只加载动态库

    复制代码 代码如下:

     g++ -c -fPIC static.cpp // 生成static.o

     ar -r libstatic.a static.o // 生成静态库libstatic.a

     g++ -c -fPIC shared.cpp // 生成shared.o

     g++ -shared shared.o -lstatic -o libshared.so   // 生成动态库libshared.so 注: -shared是g++的选项,与shared.o无关. -lstatic选项把libstatic.a的函数加入动态库中.

     g++ test.cpp -lshared -o test.exe // link libshared.so 到test.exe中.
     

    方法二:

     静态库的.o文件不用-fPIC生成. 生成动态库时不加表态库.

    生成应用程序时加载动态库和静态库.

    复制代码 代码如下:


     g++ -c static.cpp // 生成static.o

     ar -r libstatic.a static.o // 生成静态库libstatic.a

     g++ -c -fPIC shared.cpp // 生成shared.o

     g++ -shared shared.o -o libshared.so // 生成动态库libshared.so 注: -shared是g++的选项,与shared.o无关. 这时如果加-lstatic. error:relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC

     g++ test.cpp -lshared -lstatic -o test.exe // link libshared.so 到test.exe中.

      以上两种方法都无法解决我们遇到的问题。在我们的项目中,由于种种原因,不能将动态库编译进最终的项目中。

      说明一下本项目的情况:在项目中假设主控程序为main.c,动态库为libDynamic.so,静态库libStatic.a。调用情况是在main.c中需要调用libDynamic.so这个动态库,在Dynamic中又需要Static这个静态库。但是lStatic只提供库,而不提供源代码,这是最头痛的地方。最后采用了一个不是办法的办法,将静态库编译到main.c这个主控程序中,这样做的依据是,只要最终的源程序堆栈中有这个函数,就能调用到。但是直接编译将Static编译进最终的项目中。因为在main.c中并没有调用Static库中的接口函数,在编译时,-lstatic这个参数被gcc给优化掉了。要想避免这种优化,必须要main.c中调用一下这个库中的一个接口。将Static编译进main.c中控程序中后,项目运行正常。

      这种方法是没有想到更好的办法才使用的,正常情况不建议使用该方法。

      总结:从这个例子中可以证实,程序在调用函数时,是到堆栈中去找该函数的接口。堆栈的函数接口保存了一个函数指针。再利用这个函数指针来调用函数。

  • 相关阅读:
    VSCode使用笔记
    python调用C++
    ubuntu下编译C++程序
    使用swig在python中调用C++
    VSCode调试data层时自身的一个bug
    MNN配置
    金融业务中的命名惯例
    Clang的线程安全分析静态工具
    gdb命名记录
    开发小结-产品类
  • 原文地址:https://www.cnblogs.com/zxtp/p/5147608.html
Copyright © 2011-2022 走看看