=================================
版权声明
=================================
版权声明:原创文章
禁止转载
请通过右侧公告中的“联系邮箱(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
3 #ifdef SOMETHING_EXPORTS
4 #define SOMETHING_API __declspec(dllexport)
5 #else
6 #define SOMETHING_API __declspec(dllimport)
7 #endif
10 extern SOMETHING_API int nGlobalVarInDLL;
Something.cpp
1 #include "stdafx.h"
2 #include "Something.h"
5 SOMETHING_API int nGlobalVarInDLL = 233;
=======================================================================
UserA.h
1 #pragma once
3 #ifdef USERA_EXPORTS
4 #define USERA_API __declspec(dllexport)
5 #else
6 #define USERA_API __declspec(dllimport)
7 #endif
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"
4 #include <iostream>
6 #include "Something.h"
7 #pragma comment(lib,"Something.lib")
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 }
17 void CUserA::DoGet()
18 {
19 std::cout << "In UserA,nGlobalVarInDLL= " << nGlobalVarInDLL << " addr= 0x" <<(long)&nGlobalVarInDLL << std::endl;
=======================================================================
UserB.h
1 #pragma once
3 #ifdef USERB_EXPORTS
4 #define USERB_API __declspec(dllexport)
5 #else
6 #define USERB_API __declspec(dllimport)
7 #endif
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"
4 #include <iostream>
7 #include "Something.h"
8 #pragma comment(lib,"Something.lib")
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 }
17 void CUserB::DoGet()
18 {
19 std::cout << "In UserB,nGlobalVarInDLL= " << nGlobalVarInDLL << " addr= 0x" << (long)&nGlobalVarInDLL << std::endl;
=======================================================================
UserC.cpp
1 #include "stdafx.h"
3 #include "UserA.h"
4 #pragma comment(lib,"UserA.lib")
6 #include "UserB.h"
7 #pragma comment(lib,"UserB.lib")
10 int main()
11 {
12 CUserA oUserA;
13 CUserB oUserB;
15 oUserA.DoSet();
16 oUserB.DoGet();
18 oUserB.DoSet();
19 oUserA.DoGet();
21 return 0;
=======================================================================
=======================================================================
结论就是:使用的是同一个地址空间,加载的是同一个变量。
(这篇就是给那些不想学操作系统知识的人看的。)
=======================================================================
20200826-01
这里再做个扩展。所以说看博客要看原文出处,不要看垃圾爬虫网站抓取的内容。
你看,时隔多年,我还更新了!
=======================================================================
UserD是一个EXE。
编写一个UserD.cpp
1 #include <iostream>
3 #include "Something.h"
4 #pragma comment(lib,"Something.lib")
6 int main()
8 std::cout << "In UserD,nGlobalVarInDLL= " << nGlobalVarInDLL << " addr= 0x" << (long)&nGlobalVarInDLL << std::endl;
10 getchar();
12 return 0;
在Linker的Advanced里修改Base Address,这里我改了个0x20000000
运行UserC.exe和UserD.exe