精华内容
下载资源
问答
  • 可以使用动态加载或静态加载的方式使用DLL中的方法,但是怎么能够获取DLL中定义变量来使用它呢?
  • 本文主要验证动态库的全局变量和动态变量影响环境,经测试验证。动态库,代码共享,数据分离,不管是什么数据。 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个终端运行,结果互不影响:

       

    展开全文
  • 全局/静态变量跨模块(DLL)引用

    千次阅读 2018-10-08 18:23:37
    全局/静态变量作用范围为整个模块(exe\dll),如果其他模块需要引用必须显示导出,类内部的静态变量一样,只是引用范围需要加上类的作用域,这个从类声名静态变量,但是要在CPP中定义该变量可以看出,跟全局变量是...

         全局/静态变量作用范围为整个模块(exe\dll),如果其他模块需要引用必须显示导出,类内部的静态变量一样,只是引用范围需要加上类的作用域,这个从类中声名静态变量,但是要在CPP中定义该变量可以看出,跟全局变量是一样的。如果在其他模块中引用类中的静态变量必须加入dllimport导入,否则链接提示找不到该符号。

         唯有函数内部的局部静态变量不同,导出该函数的同时,或者传入该函数地址,就可以共享该静态变量,他们的地址是相同的。

         

    展开全文
  • [原]模块间(dll, exe)使用导出变量、静态变量和外部变量的试验与结论 Technorati 标签: vc,模块,导出变量,静态变量,外部变量 // Dll头文件声明 AFX_EXT_DATA int D1_nCount; extern int D1_nCountE; static ...

    [原]模块间(dll, exe)使用导出变量、静态变量和外部变量的试验与结论
    Technorati 标签: vc,模块,导出变量,静态变量,外部变量
    // Dll头文件声明

    AFX_EXT_DATA int D1_nCount;

    extern int D1_nCountE;

    static int D1_nCountS = 0;

    AFX_EXT_API int D1_GetCount();

    // 结论:多模块调用时,或重复调用时,模块内的静态变量是唯一的,不会重复分配内存
    int nCount = D1_GetCount();
    nCount = D2_GetCount();
    nCount = D1_GetCount();

    // 结论:dll中声明的静态变量在每个使用的cpp下均有一份拷贝,多模块更是如此(静态变量在编译时会分别拷贝)
    nCount = D1_nCountS;
    D1_nCountS = 2;

    // 结论:dll中声明的外部变量不能用于其他模块,链接失败(基地址都不一样,肯定不行)
    nCount = D1_nCountE;
    D1_nCountE = 2;

    // 结论:dll中导出的数据到处都可以用,在模块内部只有一份拷贝,每个用到的模块各有一份拷贝
    nCount = D1_nCount;
    D1_nCount = 2;

    ---- 2008年6月2日

    以下后续试验得出了新的结论:

    // Dll头文件声明

    #ifdef DLL2_EXPORTS
    #define D2_API        __declspec(dllexport)
    #else
    #define D2_API        __declspec(dllimport)
    #endif

    D2_API extern int D2_nCount;

    // 结论:dll中导出变量在其所在模块为导出,在其他模块必须为导入
    // 结论:dll中导出的外部变量到处都可以用,在所有模块中都只有一份拷贝
    // 结论:dll中导出的变量到处都可以用,在所有模块中都只有一份拷贝,
    // 但是在其所在模块只能包含一次(否则为重定义),所以只能声明为外部变量
    nCount = D2_nCount;
    D2_nCount = 2;

    // 总结论:dll中的变量一般情况下是以函数接口形式导出,
    // 但在某些情况下可能需要在模块间直接使用,那么就有两种方法:
    // 如果需要该变量在每个模块都有一份拷贝,那么可以使用static声明,
    // 不过这种用途一般比较少。。还有就是使用__declspec(dllexport) extern声明,
    // 一般都是需要各个模块公用一份拷贝,注意在其他模块使用时需要用
    // __declspec(dllexport)导入该变量,否则就又是导出了,而且没有实现

     

    DLL文件(Dynamic Linkable Library 即动态链接库文件),是一种不能单独运行的文件,它允许程序共享执行特殊任务所必需的代码和其他资源
    比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序 EXE 文件中,会产生一些问题:一个缺点是增加了应用程序的大小,它会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费;另一个缺点是,在编写大的 EXE 程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。
    Windows 系统平台上提供了一种完全不同的较有效的编程和运行环境,你可以将独立的程序模块创建为较小的 DLL 文件,并可对它们单独编译和测试。在运行时,只有当 EXE 程序确实要调用这些 DLL 模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了 EXE 文件的大小和对内存空间的需求,而且使这些 DLL 模块可以同时被多个应用程序使用。Windows 自己就将一些主要的系统功能以 DLL 模块的形式实现。
    一般来说,DLL 是一种磁盘文件,以.dll、.DRV、.FON、.SYS 和许多以 .EXE 为扩展名的系统文件都可以是 DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到调用进程的虚拟空间中,成为调用进程的一部分。如果与其它 DLL 之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL 模块中包含各种导出函数,用于向外界提供服务。DLL 可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个 DLL 在内存中只有一个实例;DLL 实现了代码封装性;DLL 的编制与具体的编程语言及编译器无关。
    在 Win32 环境中,每个进程都复制了自己的读/写全局变量。如果想要与其它进程共享内存,必须使用内存映射文件或者声明一个共享数据段。DLL 模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。Windows 在加载 DLL 模块时将进程函数调用与 DLL 文件的导出函数相匹配。Windows 操作系统对 DLL 的操作仅仅是把 DLL 映射到需要它的进程的虚拟地址空间里去。DLL 函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
    调用方式:
    1、静态调用方式:由编译系统完成对 DLL 的加载和应用程序结束时 DLL 卸载的编码(如还有其它程序使用该 DLL,则 Windows 对 DLL 的应用记录减1,直到所有相关程序都结束对该 DLL 的使用时才释放它,简单实用,但不够灵活,只能满足一般要求。
    隐式的调用:需要把产生动态连接库时产生的 .LIB 文件加入到应用程序的工程中,想使用 DLL 中的函数时,只须说明一下。隐式调用不需要调用 LoadLibrary() 和 FreeLibrary()。程序员在建立一个 DLL 文件时,链接程序会自动生成一个与之对应的 LIB 导入文件。该文件包含了每一个 DLL 导出函数的符号名和可选的标识号,但是并不含有实际的代码。LIB 文件作为 DLL 的替代文件被编译到应用程序项目中。
    当程序员通过静态链接方式编译生成应用程序时,应用程序中的调用函数与 LIB 文件中导出符号相匹配,这些符号或标识号进入到生成的 EXE 文件中。LIB 文件中也包含了对应的 DL L文件名(但不是完全的路径名),链接程序将其存储在 EXE 文件内部。
    当应用程序运行过程中需要加载 DLL 文件时,Windows 根据这些信息发现并加载 DLL,然后通过符号名或标识号实现对 DLL 函数的动态链接。所有被应用程序调用的 DLL 文件都会在应用程序 EXE 文件加载时被加载在到内存中。可执行程序链接到一个包含 DLL 输出函数信息的输入库文件(.LIB文件)。操作系统在加载使用可执行程序时加载 DLL。可执行程序直接通过函数名调用 DLL 的输出函数,调用方法和程序内部其 它的函数是一样的。
    2、动态调用方式:是由编程者用 API 函数加载和卸载 DLL 来达到调用 DLL 的目的,使用上较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。
    显式的调用:
    是指在应用程序中用 LoadLibrary 或 MFC 提供的 AfxLoadLibrary 显式的将自己所做的动态连接库调进来,动态连接库的文件名即是上面两个函数的参数,再用 GetProcAddress() 获取想要引入的函数。自此,你就可以象使用如同本应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用 FreeLibrary 或 MFC 提供的 AfxFreeLibrary 释放动态连接库。直接调用 Win32 的 LoadLibary 函数,并指定 DLL 的路径作为参数。LoadLibary 返回 HINSTANCE 参数,应用程序在调用 GetProcAddress 函数时使用这一参数。GetProcAddress 函数将符号名或标识号转换为 DLL 内部的地址。程序员可以决定 DLL 文件何时加载或不加载,显式链接在运行时决定加载哪个 DLL 文件。使用 DLL 的程序在使用之前必须加载(LoadLibrary)加载DLL从而得到一个DLL模块的句柄,然后调用 GetProcAddress 函数得到输出函数的指针,在退出之前必须卸载DLL(FreeLibrary)。
    正因为DLL 有占用内存小,好编辑等的特点有很多电脑病毒都是DLL格式文件。但不能单独运行。
    动态链接库通常都不能直接运行,也不能接收消息。它们是一些独立的文件,其中包含能被可执行程序或其它DLL调用来完成某项工作的函数。只有在其它模块调用动态链接库中的函数时,它才发挥作用。

    打得累死了,大哥你多给积分吧

    展开全文
  • DLL中导出全局变量

    千次阅读 2010-05-21 17:01:00
    DLL定义的全局变量可以被调用进程访问;DLL也可以访问调用进程的全局数据,我们来看看在应用工程引用DLL中变量的例子(单击此处下载本工程)。#ifndef LIB_H#define LIB_Hextern int dllGlobalVar;#endif#include ...


      DLL定义的全局变量可以被调用进程访问;DLL也可以访问调用进程的全局数据,我们来看看在应用工程中引用DLL中变量的例子(单击此处下载本工程)。



    #ifndef LIB_H
    #define LIB_H
    extern int dllGlobalVar;
    #endif



    #include "lib.h"
    #include <windows.h>

    int dllGlobalVar;

    BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
     switch (ul_reason_for_call)
     {
      case DLL_PROCESS_ATTACH:
       dllGlobalVar = 100; //在dll被加载时,赋全局变量为100
       break;
      case DLL_THREAD_ATTACH:
      case DLL_THREAD_DETACH:
      case DLL_PROCESS_DETACH:
       break;
     }
     return TRUE;
    }


      ;文件名:lib.def

      ;在DLL中导出变量

    LIBRARY "dllTest"

    EXPORTS

    dllGlobalVar CONSTANT

    ;或dllGlobalVar DATA

    GetGlobalVar


      从lib.h和lib.cpp中可以看出,全局变量在DLL中的定义和使用方法与一般的程序设计是一样的。若要导出某全局变量,我们需要在.def文件的EXPORTS后添加:

      变量名 CONSTANT   //过时的方法

      或

      变量名 DATA     //VC++提示的新方法

      在主函数中引用DLL中定义的全局变量:

    #include <stdio.h>

    //加载静态链接库dllTest.lib
    #pragma comment(lib,"dllTest.lib")

    extern int dllGlobalVar;

    int main(int argc, char *argv[])
    {
     printf("%d ", *(int*)dllGlobalVar);
     *(int*)dllGlobalVar = 1;
     printf("%d ", *(int*)dllGlobalVar);
     return 0;
    }


      特别要注意的是用extern int dllGlobalVar声明所导入的并不是DLL中全局变量本身,而是其地址,应用程序必须通过强制指针转换来使用DLL中的全局变量。这一点,从*(int*)dllGlobalVar可以看出。因此在采用这种方式引用DLL全局变量时,千万不要进行这样的赋值操作:

    dllGlobalVar = 1;


      其结果是dllGlobalVar指针的内容发生变化,程序中以后再也引用不到DLL中的全局变量了。

      在应用工程中引用DLL中全局变量的一个更好方法是:

    #include <stdio.h>
    #pragma comment(lib,"dllTest.lib")

    extern int _declspec(dllimport) dllGlobalVar; //用_declspec(dllimport)导入
    int main(int argc, char *argv[])
    {
     printf("%d ", dllGlobalVar);
     dllGlobalVar = 1; //这里就可以直接使用, 无须进行强制指针转换
     printf("%d ", dllGlobalVar);
     return 0;
    }


      通过_declspec(dllimport)方式导入的就是DLL中全局变量本身而不再是其地址了,笔者建议在一切可能的情况下都使用这种方式。

    展开全文
  • 今天偶然间遇到一个BUG,我主工程和一个DLL工程同时使用了同一个lib静态成员变量。调试过程就发现静态成员变量赋值后,到DLL中竟然没有值。  后来发现原来主工程和DLL工程有各自生成了一个静态成员变量,...
  • lib和dll中的全局变量

    2015-04-27 14:46:18
    lib: lib的全局变量在链接它的单元是可以通过extern访问到的,...在lib的cpp中定义一个静态变量会被所有用到这个lib的模块公用,在链接一个程序的时候会自动的去掉重复链接的lib保证某个lib只有一份代码存在,
  • // Dll头文件声明 AFX_EXT_DATA int D1_nCount; extern int D1_nCountE; static int D1_nCountS = ... // 结论:多模块调用时,或重复调用时,模块内的静态变量是唯一的,不会重复分配内存int nCount = D1_GetCount();n
  • 【心得】在C#使用静态变量const和动态变量readonly的区别 今天看了一篇文章,介绍了在《Effictive C#》静态变量和动态变量的说明和各自的优缺点。 对于在定义常量的时候,到底是用const来定义还是readonly来...
  • 动态库的全局变量与静态变量

    千次阅读 2020-03-10 10:28:04
    写一个so,该so有一个全局变量。so的代码在运行时会修改该全局变量的值。然后,有多个程序都需要该so,而且这些应用程序都启动了。此时,很显然so只被加载了一份,那么,当这么多程序在运行调用该so时,该so的...
  • 概念首先得明白局部变量静态局部变量,全局变量静态全局变量这几个概念,以下面程序举例://main....全局变量:具有全局作用域,全局变量只需在一个源文件中定义,就可以作用于所有的源文件。 静态全局变量:具有全
  • c++内存到底分几个区? 一:  1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构的栈... 3、全局区(静态区)(static)—,全局变量和静态变量的存储是
  • 1、static关键字作用 1.1 隐藏   ...//a.c文件 char a = 'A'; void msg() {  printf("Hello\n"); } //main.c文件 extern char a; printf("%c",a); 输出结...
  • 当调用的DLL中有全局变量时调用它的多个实例是否共享同一个全局变量????? 收藏 当调用的DLL中有全局变量时调用它的多个实例是否共享同一个全局变量????问题的起因原于自己在工作需要调用一个动态库,而其中要...
  • 先建一个MFC扩展DLL项目。加入类定义: //Point.hclass AFX_EXT_CLASS Point{private: int _x; int _y;public: explicit Point(int x, int y): _x(x), _y(y) {} int get_x() {return _x;} int get
  • 1、error LNK2005: "public: void __thiscall std::basic_ofstream&lt;char,struct std::char_traits&lt;char&...第一种:在dll静态库种不要使用stl中变量作为接口。 第二种:在li...
  • 全局和静态变量都在堆里。 <br /> 全局变量的作用范围是整个程序(如果程序是多个文件,必须在其他的文件说明)。 静态变量的作用范围要看静态变量的位置,如果在函数里,则作用范围就是...
  • MFC中静态变量销毁的奇怪Bug

    千次阅读 2012-12-08 09:58:53
    问题出现: 在MFC工程,本来想在程序写Log的,直接写了一个Log的类,进行了相关控制,但是在程序...因为写的是DLL,在DLL初始化时候的APP里Instance中定义了局部静态Log对象,所以怀疑是不是Instance有什么不同,
  • 静态变量的导出

    千次阅读 2015-08-19 18:08:44
    现在一般工程都比较多,很多情况下都有基础的一些工具库,关于库的导出和其他工程引用这个库的时候有些需要注意的,...#define _DLL_H_//防重复定义 #if BUILDING_DLL #define DLLIMPORT __declspec (dllexport) #el
  • 可写静态数据在EKA1的DLL中是不允许的,因为EKA1DLL具有分离的程序代码和只读数据区域,没有可写数据的... 正常情况下,如果在DLL中加入可写静态数据(如全局变量)当编译真机版DLL代码时,返产生编译错误"XXX.dl
  • 今天在公司干完活后思考了lib和dll的链接性,然后做了测试,发现和我想象的不大相同,具体总结如下:lib: lib的全局变量在链接它的单元是可以通过extern访问到的,但是链接它的单元如果定义了一个相同的全局...
  • 静态变量VS自动变量(动态变量): 什么是自动变量呢?自动变量就是指在函数内部定义使用的变量。他只是允许在定义他的函数内部使用它。在函数外的其他任何地方都不能使用的变量。自动变量是局部变量,即它的区域性是...
  • VC如何定义全局变量

    千次阅读 2012-04-10 22:01:43
    问:VC如何定义全局变量 答:  放在任意文件里   在其他文件里用 extern 声明   或者在App类声明一个公有成员   在程序其它类可以用  ... MFC中定义只有静态成员的类 到时候直接应用就可以了,
  • C++:类静态变量的导出

    千次阅读 2016-12-06 22:21:47
    动态链接库导出静态成员变量 导出库头文件#pragma once #include "afx.h" #include <conio.h>#ifdef BUILDING_DLL //在stdafx.h中定义 #define DLLIMPORT __declspec (dllexport) #else #define DLLIMPORT __...
  • 当调用的DLL中有全局变量时调用它的多个实例是否共享同一个全局变量????问题的起因原于自己在工作需要调用一个动态库,而其中要用到一个全局的变量才能把需要的句柄给传出来,于是就想,如果有多个进程要调用...
  • DLL:线程局部变量

    千次阅读 2006-05-11 11:46:00
    注意事项:当用__declspec(thread)声明线程局部变量的时候,应注意以下事项:1>只能用来声明或者定义具有static作用域的变量,而不能用来声明或者定义局部变量,函数,类,类型.其中具有static作用域的变量包括全局对象...
  • 下面有几种网上的理解,我整理一下:一: 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构的栈。 2、堆区(heap) — 一般由程序员分配释放, 若程序员...
  • 关于MFC dll的相关知识很多很杂,这里特酷吧结合自己学习遇到的问题专门整理了一些MFC dll的基础知识。本部分共上下两篇文章,本文为上篇,MFC DLL应用程序类型分为以下三种: (1)使用共享MFC DLL的规则DLL (2)...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,444
精华内容 17,777
关键字:

dll中定义的静态变量