精华内容
下载资源
问答
  • 2020-06-03 11:06:01

    问题描述

    回归正题,前段时间项目开发中,实现了一个动态库,封装了一些方法。然后基于这个动态库,实现了一个应用程序。应用程序中含有全局变量A,动态库中也含有全局变量A,当我调用动态库中函数后,发现应用程序的A发生了变化!!!O,My God!对于我这种还没在Linux下做过开发的人来说,一头雾水。。。。。。 于是我尝试着,将A中的变量名称改为B,这样问题也就没有了~~~

     

    原因

     

    应用程序进行链接的时候,动态库中全局变量定义,将会被应用程序中同名的全局变量所覆盖。这样也就造成了,在动态库中修改A变量时,应用程序中的A也发生了变化。

    解决方法

    在创建动态链接库时,gcc/g++选项中添加编译选项

    -Wl,-Bsymbolic.


    其中Wl表示将紧跟其后的参数,传递给连接器ld。Bsymbolic表示强制采用本地的全局变量定义,这样就不会出现动态链接库的全局变量定义被应用程序的同名定义给覆盖了!

     

    https://blog.csdn.net/lcalqf/article/details/78129697?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-26.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-26.nonecase

    更多相关内容
  • 在A中定义有全局变量X(或类的静态成员变量),则在动态库B中访问的X,与可执行程序C中访问的X是同一个变量还是两个不同的变量? 答案:是两个不同的变量。 2. 工程中包含动态库A,动态库B,可执行程序C。C依赖于A和...
  • 本文主要验证动态库全局变量和动态变量影响环境,经测试验证。动态库,代码共享,数据分离,不管是什么数据。 Compute.h:代码如下: #ifndef __COMPUTE_H #define __COMPUTE_H int GetResult(); int ...

    本文主要验证动态库的全局变量和动态变量影响环境,经测试验证。动态库,代码共享,数据分离,不管是什么数据。

    Compute.h:代码如下:

    #ifndef __COMPUTE_H
    #define __COMPUTE_H

    int GetResult();
    int GetStaticResult();

    #endif

     

    Compute.cpp:代码如下:

    #include "Compute.h"

    static int gn_test = 1;
    int GetResult(){
        ++gn_test;

        return gn_test;
    }

    int GetStaticResult(){
        static int s_nTest = 1;
        ++s_nTest;

        return s_nTest;
    }

     

    main.cpp代码如下:

    #include "Compute.h"

    #include <iostream>
    #include <thread>
    #include <chrono>

    void ShowValue(){
        while(true){
            std::this_thread::sleep_for(std::chrono::seconds(2));
            std::cout << "Value:" << GetResult() << std::endl;
            std::cout << "Static value:" << GetStaticResult() << std::endl;
        }
    }

    int main(int argc, char**argv){
        std::thread tTask(ShowValue);

        tTask.join();

        return 0;
    }

    编译选项如下:

         1、先生成动态库:

    g++ -fPIC -shared -o libCompute.so Compute.cpp

        2、生成执行文件,并链接动态库

                g++ main.cpp -lpthread -L . -lCompute -o test

        3、拷贝文件到搜索目录

         $ sudo cp libCompute.so /usr/lib/

        4、在2个终端运行,结果互不影响:

       

    展开全文
  • 全局变量使用一、全局变量的定义和基础使用二、全局变量被其它文件使用三、全局变量动态链接中定义,被外部文件使用 一、全局变量的定义和基础使用 全局变量一般定义在一个.cpp文件的头部, 供所在文件乃至其它...

    一、全局变量的定义和基础使用

    全局变量一般定义在一个.cpp文件的头部, 供所在文件乃至其它文件共享使用,供其它文件使用时,不能声明为静态static。

    示例1

    Test1.cpp
    
    #inclue <stdio.h>
    
    char cTest1[32] = "Hello World!\n";
    char cTest2[32] = "Hello My World!\n";
    
    int print_test()
    {
        printf("%s", cTest2);    //直接使用全局变量cTest2
        return 0;
    }
    
    int main()
    {
      //打印出  Hello World!
        printf("%s", cTest1);            //直接使用全局变量cTest1
    
      //打印出 Hello My World!
        print_test();               
             
        return 0;
    }
    

    二、全局变量被其它文件使用

    全局变量被其它文件可访问,需要有两个基本条件:

    ①变量不能声明为静态,否则只能被全局变量所在文件访问,如下示例2是不可以的,按示例1处理即可。

    示例2

    Test2.cpp
    
    #inclue <stdio.h>
    
    
    static char cTest1[32] = "Hello World!\n";            //由于使用static关键字修饰,因此只能被本.cpp的成员使用, 其它文件不可见
    static char cTest2[32] = "Hello My World!\n";
    
    
    int print_test()
    {
        printf("%s", cTest2);    //直接使用全局变量cTest2
        return 0;
    }
    
    
    int main()
    {
      //打印出  Hello World!
        printf("%s", cTest1);            //直接使用全局变量cTest1
    
    
      //打印出 Hello My World!
        print_test();               
             
        return 0;
    }
    

    ②定义全局变量对应的头文件中或其它使用全局变量的文件中,使用extern关键字声明全局变量

    (1) 在.h文件中声明

    示例3(全局变量的定义如示例1):

    Test1.h
    
    extern char char cTest1[32];
    extern char char cTest2[32];
    
    Test3.cpp
    
    #include <stdio.h>
    #include "Test1.h"    //inculde 被extern 修饰的全局变量所在的头文件
    
    int print_test3()
    {
        printf("%s",cTest1);   // 使用全局变量 //当程序被执行时 打印出  Hello World!
        printf("%s",cTest2);   // 使用全局变量 //当程序被执行时 打印出 Hello My World!
        return 0;
    }
    

    (2) 在调用全局变量的文件中声明

    示例4(全局变量的定义如示例1):

    Test:4.cpp
    
    #include <stdio.h>
    
    extern char char cTest1[32];    
    extern char char cTest2[32];
    
    int print_test3()
    {
        printf("%s",cTest1);   // 使用全局变量 //当程序被执行时 打印出  Hello World!
        printf("%s",cTest2);   // 使用全局变量 //当程序被执行时 打印出 Hello My World!
        return 0;
    }
    

    本人的使用习惯是二者同时使用,既在头文件中声明,也在调用的文件中声明。

    三、全局变量在动态链接库中定义,被外部文件使用

    动态链接库中的全局变量被其它文件可访问,需要有三个基本条件:
    ①②同上一节中
    ③在全局变量定义文件中,使用__declspec(dllexport) 声明输出;在全局变量调用的外部文件中,使用__declspec(dllimport)声明输入

    针对条件③进行说明:

    方便起见,使用如下方式,通过定义宏的方式,定义上面的导入和导出声明
    
    #ifdef _LIBDATAPRO1_EXPORTS    //该宏在VS中, “项目” → “右键” → “属性” → “属性配置” → “C/C++” → “预处理器” → “预处理器定义” 中添加
    #define LIBCFGPARA_API __declspec(dllexport)    //若 _LIBDATAPRO1_EXPORTS  已定义 则  LIBCFGPARA_API 定义为输出  __declspec(dllexport)
    #else
    #define LIBCFGPARA_API __declspec(dllimport)    //若 _LIBDATAPRO1_EXPORTS  未定义 则  LIBCFGPARA_API 定义为输   __declspec(dllimport)
    #endif // _LIBDATAPRO_EXPORT
    

    示例5

    Test5.cpp
    
    #inclue <stdio.h>
    
    LIBCFGPARA_API char cTest1[32] = "Hello World!\n";            //使用 LIBCFGPARA_API 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllexport)   
    LIBCFGPARA_API char cTest2[32] = "Hello My World!\n";         //使用 LIBCFGPARA_API 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllexport)   
    
    Test5.h
    
    #ifdef _LIBDATAPRO1_EXPORTS    //该宏在VS中, “项目” → “右键” → “属性” → “属性配置” → “C/C++” → “预处理器” → “预处理器定义” 中添加
    #define LIBCFGPARA_API __declspec(dllexport)    //若 _LIBDATAPRO1_EXPORTS  已定义 则  LIBCFGPARA_API 定义为输出  __declspec(dllexport)
    #else
    #define LIBCFGPARA_API __declspec(dllimport)    //若 _LIBDATAPRO1_EXPORTS  未定义 则  LIBCFGPARA_API 定义为输   __declspec(dllimport)
    #endif // _LIBDATAPRO_EXPORT
    
    
    LIBMAKEPRE_API extern char char cTest1[32];                //使用 LIBCFGPARA_API 配合 extern 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllexport)   
    LIBMAKEPRE_API extern char char cTest2[32];                //使用 LIBCFGPARA_API 配合 extern 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllexport)   
    

    将上述Test5项目(含Test5.cpp 和 Test5.h文件)进行编译,生成动态链接库,得到Test5.dll和Test5.lib两文件。

    Test6.cpp
    
    #include <stdio.h>
    #inclue "Test5.h"                                        //(1) include 全局变量对应的Test5.h文件。     由于外部文件的项目中,并没有定义 _LIBDATAPRO1_EXPORTS,因此 LIBCFGPARA_API 被 #else 分支 定义为 __declspec(dllimport)   
    
    #pragma comment(lib, "../x64/Debug/Test5.lib")           //(2) 引用编译生成的.lib库文件
    
    LIBMAKEPRE_API extern char char cTest1[32];              //(3) 使用 LIBCFGPARA_API 配合 extern 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllimport)   
    LIBMAKEPRE_API extern char char cTest2[32];              //(3) 使用 LIBCFGPARA_API 配合 extern 声明全局变量为输出形式  LIBCFGPARA_API 为  __declspec(dllimport)   
    
    int print_test()
    {
        printf("%s", cTest2);    //直接使用全局变量cTest2
        return 0;
    }
    
    int main()
    {
      //打印出  Hello World!
        printf("%s", cTest1);            //直接使用全局变量cTest1
    
    
      //打印出 Hello My World!
        print_test();               
             
        return 0;
    }
    

    注意:若外部文件在在使用全局变量时, 没有使用输入声明 __declspec(dllimport) ,则VS编译时会有“无法解析的外部符号”编译错误,对比结果如下图所示。

    示例6(无 __declspec(dllimport) 声明,编译出错):
    在这里插入图片描述
    示例6(有 __declspec(dllimport) 声明,编译成功):
    在这里插入图片描述
    至此,动态链接库中的全局变量,实现了被外部文件的使用。

    展开全文
  • C++又一坑:动态链接中的全局变量

    千次阅读 2019-07-25 11:00:49
    在Linux中,载入的动态链接实际上可以直接使用外部框架或者其他模块的全局数据,但是在Windows下确是隔离的,不直接访问到。 另外, 我从另一篇文章上看到,这个行为与 dlopen 时flag是 RTLD_GLOBAL 还是 RTLD_...
     
    1.  
    2.  
    3. extern "C" {

    4.  
    5. void dll_func() {

    6. foo_class::_.m += 100;

    7. printf("&foo_class::_ = 0x%llx, foo_class::_.m = %d\n", &foo_class::_, foo_class::_.m);

    8. }

    9.  
    10. }

    编译选项:

    gcc -O0 -g -ggdb c.cpp -o libtest_c.so -shared -fPIC -L$PWD -ltest_a -lstdc++

    这是三个模块的代码和编译选项。我分别至于Linux和Windows内的GCC编译测试。
    Linux中的GCC 4.4.6 运行结果如下:

    foo_class::foo_class(), this-> 0x600f98
    &foo_class::_ = 0x600f98, foo_class::_.m = 1010
    foo_class::foo_class(), this-> 0x600f98
    &foo_class::_ = 0x600f98, foo_class::_.m = 110
    foo_class::~foo_class(), this-> 0x600f98
    foo_class::~foo_class(), this-> 0x600f98

    从结果中可以看出来,在Linux中多个动态链接库和主程序引用的同一个全局变量(地址相同),但是每一个二进制实例都会完成一次构造。这就造成了同一个实例多次构造,导致我们最初碰到的结果。

    Windows中Cygwin的GCC 4.8.2 中运行结果如下:

    foo_class::foo_class(), this-> 0x100406010
    &foo_class::_ = 0x100406010, foo_class::_.m = 1010
    foo_class::foo_class(), this-> 0x5aa426010
    &foo_class::_ = 0x5aa426010, foo_class::_.m = 110
    foo_class::~foo_class(), this-> 0x5aa426010
    foo_class::~foo_class(), this-> 0x100406010

    但是在Windows中,虽然每个动态链接库和主程序引用的同一个全局变量也各自都执行了一次构造。但是,每一个二进制内的全局变量,实际上并不是同一个。他们并不冲突,但是他们也不在一个内存区域内,所以即便是纯C下和Linux内的行为也不一样。

    这也就意味着,在Linux中,载入的动态链接库实际上可以直接使用外部框架或者其他模块的全局数据,但是在Windows下确是隔离的,不能直接访问到。
    另外, 我从另一篇文章上看到,这个行为与dlopen时flag是RTLD_GLOBAL还是RTLD_LOCAL有关。但是我这里实测没有任何变化。但是结果和编译选项-fPIC有关(原因去看gcc文档吧,我就不复述啦)。
    PS: 如果不是直接使用的全局变量,而是直接使用函数接口,并且返回一个static的局部变量这种方式,测试结果也是一样的;
    而且如果不是通过dlopen动态加载,而是通过编译时链接进去的话,也是构造了两次。
    这里就不再另外贴出输出结果了。

    其实,根本问题是多个动态链接库里共享的内存对象的构造问题。在不同环境下有不同的行为,也许会藏地比较隐晦。着实是个坑呐。

    展开全文
  • 动态链接全局变量问题

    千次阅读 2020-04-02 20:07:08
    请问动态链接库被外部多次调用时,每次调用中动态库自身的全局变量都会重新初始化吗?如果会那怎么来使我每次调用动态库时都从上次的状态开始执行呢? 你这个问题得分被调用的是同一个进程还是不同的进程。如果是...
  • 动态链接全局变量与多线程

    千次阅读 2018-09-30 16:48:16
    最近对多线程调用时,动态链接全局变量有了以下几点认识。 1、动态链接被同一进程的多个线程加载时,全局变量的值是进程有效。  例如:动态链接C.dll有一个全局变量 int g_iCount=0(初始值)。某一函数...
  • 在C语言的学习过程中,会涉及到**局部变量和全局变量的内存分配和内存释放**问题
  • 最近看代码,发现一个在动态库中在全局变量A,我在动态库外部extern引用的时候总是提示undefined错误。首先确认在引用同一个动态库中的API函数B没有问题。首先看来下动态库中,readelf命令导出文件的信息,发现:1....
  • C语言全局变量和局部变量总结

    千次阅读 多人点赞 2018-08-28 15:01:10
    外部变量(即全局变量)是在函数的外部定义的, 它的作用域为从变量定义处开始,到本程序文件的末尾。 如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用该...
  • static变量与全局变量

    千次阅读 2019-11-07 20:44:25
    一、程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分: 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的...
  • 用vs编译动态库如果配置错误会导致全局变量初始化。 例子: string a="hello"; char b="hello"; int main(int arg,char* argv[]) { printf("string a=%s",a.c_str()); printf("char* b=%s",b); } ...
  • 全局变量和静态变量初始化总结

    千次阅读 2022-03-28 10:43:32
    c++保证,全局变量在main函数第一次使用它之前,就把它初始化好。【可以直接理解成在main函数执行前就初始化好】但这个初始化可细分为:编译时初始化和运行时初始化,即static initialization和dynamic ...
  • 动态共享编译的时候,对于全局变量,一律视为模块间变量访问。 变量会通过数据段的GOT表来访问。 而且,当可执行文件中(由于可执行文件不是PIC的)有同名全局变量时,共享中定义的变量会被ignore,进程中只会...
  • 头文件中定义全局变量

    千次阅读 2020-08-14 21:11:05
    这些天写的程序中用到了全局变量,一开始是在一个文件下做测试后来把文件按逻辑拆分了一下,不同的代码被放在了几个文件中,最后用Makefile来编译就遇到了今天的话题,怎么在头文件中定义全局变量呢? 做法 要想一个...
  • 全局变量和静态变量的区别

    千次阅读 2014-06-08 23:15:11
    全局变量具有外部连接性,即同一工程中其它文件中的也可引用。 而静态变量不具有外部连接性,即同一工程中其它文件中不可以引用。 如: //cpp1.cpp extern int x=10; static int y=5; //cpp2.cpp #include  ...
  • PHP 和 JavaSript 区别_后端开发PHP是一种...C语言中在main函数中定义的变量不是全局变量,而是局部变量。main函数中定义的变量与全局变量的生命周期一样长。(推荐教程:C语言教程)注意:全局变量一定是定义在函数...
  • 进程间是相互独立的,其实完全可以看成A、B两个进程各自有一份单独的liba.so和libb.so,相应的动态库的代码段和数据段都是各个进程各自有一份的。 然后在这个基础上,由于代码段是不会被修改的,所以操作系统可以...
  • QT编程之——使用全局变量

    万次阅读 2014-05-19 08:35:54
    在Qt中使用全局变量的实例 1.首先需要在一个头文件中对全局了变量使用exern方法进行定义。 //g.h extern char *testStr; 2.只能在cpp文件中对其是实例化,并且实例化只能在函数的外部进行。建议在包含main函数的cpp...
  •   很多人可能直接把全局变量写进.h文件,然后用多个文件包含这个...那其他文件如何使用这些全局变量呢? 全局变量要在.h 文件中声明,在.cpp文件中定义。定义好了之后,可以在.h文件中利用extern关键字进行声明...
  • 动态库内容分析 文章目录动态库内容分析1. 动态库编译1.1 第一个C文件:basic.c1.2第二个C文件:demo.c1.3第三个C文件:main.c2.动态库编译3.二进制内容分析3.1 libbasic.so分析3.1.1 basic.c内容汇总3.1.2 libbasic...
  • JS 基础之全局变量,局部变量

    千次阅读 2018-08-23 09:56:29
    本章将概要介绍一些编写高质量JavaScript的最佳实践、模式和习惯,比如避免全局变量使用单var声明、预缓存循环中的length、遵守编码约定等等。本章还包括一些编程习惯,这些习惯跟具体的代码关系不大,而是更多...
  • extern声明的全局变量的作用范围是整个工程,我们通常在“.h”文件中声明extern变量之后,在其他的“.c”或者“.cpp”中都可以使用。extern扩大了全局变量的作用域范围,拓展到整个工程文件中。 我们注意的问题是...
  • 要用全局变量,需要使用"::"  局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环...
  • 4 动态库的加载及调用 动态库的加载分为静态加载、动态加载两种方式。 4.1 静态加载动态库 静态加载动态库的步骤包括:设置项目附加库目录;设置项目附加依赖项;移动DLL文件以及声明动态库的导出函数。 创建...
  • static变量与全局、局部... 而静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,
  • c语言中存在静态库(.a)和动态库(.so)。 静态库实际上是一些目标文件的集合,只用于链接生成可执行文件阶段。链接器会将程序中使用到函数的代码从库文件中拷贝到应用程序中,一旦链接完成生成可执行文件之后,在执行...
  • 全局变量和局部变量在内存中的区别 C语言经过编译之后将内存分为以下几个区域: (1)栈(stack):由编译器进行管理,自动分配和释放,存放函数调用过程中的各种参数、局部变量、返回值以及函数返回地址。操作...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 68,877
精华内容 27,550
关键字:

动态库能使用外部全局变量吗