• DLL导出全局变量在多个DLL中调用


    =================================版权声明=================================

    版权声明:原创文章 禁止转载 

    请通过右侧公告中的“联系邮箱(wlsandwho@foxmail.com)”联系我

    勿用于学术性引用。

    勿用于商业出版、商业印刷、商业引用以及其他商业用途。                   

    本文不定期修正完善。

    本文链接:http://www.cnblogs.com/wlsandwho/p/6716215.html

    耻辱墙:http://www.cnblogs.com/wlsandwho/p/4206472.html

    =======================================================================

    本文讲解了从一个DLL中导出的全局变量,在程序的多个不同DLL中使用时,该变量的行表现。

    =======================================================================

    Something、UserA、UserB是三个DLL,UserC是一个EXE。

    Something在UserA、UserB中被调用,UserC调用了UserA和UserB。

    =======================================================================

    Something.h

     1 #pragma once
     2 
     3 #ifdef SOMETHING_EXPORTS
     4 #define SOMETHING_API __declspec(dllexport)
     5 #else
     6 #define SOMETHING_API __declspec(dllimport)
     7 #endif
     8 
     9 
    10 extern SOMETHING_API int nGlobalVarInDLL;

    Something.cpp

    1 #include "stdafx.h"
    2 #include "Something.h"
    3 
    4 
    5 SOMETHING_API int nGlobalVarInDLL = 233;

    =======================================================================

    UserA.h

     1 #pragma once
     2 
     3 #ifdef USERA_EXPORTS
     4 #define USERA_API __declspec(dllexport)
     5 #else
     6 #define USERA_API __declspec(dllimport)
     7 #endif
     8 
     9 
    10 class USERA_API CUserA
    11 {
    12 public:
    13     void DoSet();
    14     void DoGet();
    15 };

    UserA.cpp

     1 #include "stdafx.h"
     2 #include "UserA.h"
     3 
     4 #include <iostream>
     5 
     6 #include "Something.h"
     7 #pragma comment(lib,"Something.lib")
     8 
     9 
    10 void CUserA::DoSet()
    11 {
    12     std::cout <<"In UserA,nGlobalVarInDLL=    "<< nGlobalVarInDLL <<"        addr=    0x"<<(long)&nGlobalVarInDLL << std::endl;
    13     nGlobalVarInDLL = 1;
    14     std::cout << "In UserA,We set nGlobalVarInDLL=    " << nGlobalVarInDLL <<std::endl;
    15 }
    16 
    17 void CUserA::DoGet()
    18 {
    19     std::cout << "In UserA,nGlobalVarInDLL=    " << nGlobalVarInDLL << "    addr=    0x" <<(long)&nGlobalVarInDLL << std::endl;
    20 }

    =======================================================================

    UserB.h

     1 #pragma once
     2 
     3 #ifdef USERB_EXPORTS
     4 #define USERB_API __declspec(dllexport)
     5 #else
     6 #define USERB_API __declspec(dllimport)
     7 #endif
     8 
     9 
    10 class USERB_API CUserB
    11 {
    12 public:
    13     void DoSet();
    14     void DoGet();
    15 };

    UserB.cpp

     1 #include "stdafx.h"
     2 #include "UserB.h"
     3 
     4 #include <iostream>
     5 
     6 
     7 #include "Something.h"
     8 #pragma comment(lib,"Something.lib")
     9 
    10 void CUserB::DoSet()
    11 {
    12     std::cout << "In UserB,nGlobalVarInDLL=    " << nGlobalVarInDLL << "    addr=    0x" << (long)&nGlobalVarInDLL << std::endl;
    13     nGlobalVarInDLL = 2;
    14     std::cout << "In UserB,We set nGlobalVarInDLL=    " << nGlobalVarInDLL << std::endl;
    15 }
    16 
    17 void CUserB::DoGet()
    18 {
    19     std::cout << "In UserB,nGlobalVarInDLL=    " << nGlobalVarInDLL << "    addr=    0x" << (long)&nGlobalVarInDLL << std::endl;
    20 }

    =======================================================================

    UserC.cpp

     1 #include "stdafx.h"
     2 
     3 #include "UserA.h"
     4 #pragma comment(lib,"UserA.lib")
     5 
     6 #include "UserB.h"
     7 #pragma comment(lib,"UserB.lib")
     8 
     9 
    10 int main()
    11 {
    12     CUserA oUserA;
    13     CUserB oUserB;
    14 
    15     oUserA.DoSet();
    16     oUserB.DoGet();
    17 
    18     oUserB.DoSet();
    19     oUserA.DoGet();
    20 
    21     return 0;
    22 }

    =======================================================================

    调用结果

    =======================================================================

    结论就是:使用的是同一个地址空间,加载的是同一个变量。

    (这篇就是给那些不想学操作系统知识的人看的。)

    =======================================================================

    20200826-01

    这里再做个扩展。所以说看博客要看原文出处,不要看垃圾爬虫网站抓取的内容。

    你看,时隔多年,我还更新了!

    =======================================================================

    UserD是一个EXE。

    编写一个UserD.cpp

     1 #include <iostream>
     2 
     3 #include "Something.h"
     4 #pragma comment(lib,"Something.lib")
     5 
     6 int main()
     7 {
     8     std::cout << "In UserD,nGlobalVarInDLL=    " << nGlobalVarInDLL << "        addr=    0x" << (long)&nGlobalVarInDLL << std::endl;
     9 
    10     getchar();
    11 
    12     return 0;
    13 }

    在Linker的Advanced里修改Base Address,这里我改了个0x20000000

    运行UserC.exe和UserD.exe

     

     发现地址不一样。

    再运行一次。

     

    发现地址又是一样的。

    这里微软的意思是,不同进程加载同一个DLL,其载入的地址可能是一样的也可能是不一样的,但无论一样不一样,都是独立的互不影响的。

  • 相关阅读:
    SDOI2017 R2泛做
    类似静态区间逆序对的题的一些做法
    友链&&日记
    注意事项以及一些奇怪的姿势
    关于各种算法以及好的blog的整理(持续更新)
    PKUSC2019游记
    洛谷P5398 [Ynoi2018]GOSICK(二次离线莫队)
    洛谷P4887 第十四分块(前体)(二次离线莫队)
    [51nod]1678 lyk与gcd(莫比乌斯反演)
    LOJ#557. 「Antileaf's Round」你这衣服租来的吗(FHQ Treap+珂朵莉树)
  • 原文地址:https://www.cnblogs.com/wlsandwho/p/6716215.html
Copyright © 2020-2023  润新知