DLL file mapping

本文探讨了DLL中导出变量的行为,特别是在不同进程间共享变量时的情况。实验表明每个进程都拥有独立的数据副本,即使这些数据是从同一个DLL导入的。此外,还讨论了两个包含相同函数名的DLL如何被链接的问题。

        -- DLL notes 2 of <Windows via C/C++>

 

Let’s begin this topic with a question about exporting variables in DLL:

Assume one process import a variable from a DLL, and change the value, then if another process import the same variable from the DLL, will the variable have the value the former process assigned?

I once thought the data should be the same to all the processes, because the DLL have been mapped into to all process’ address. To insure my thoughts I did a little experiment. But the test result is opposite: Each process have a separate copy of data, including integer and char array type.

According to the test result, I think, all the function is mapped into the process’s virtual address, but the variable outputted is allocated in the process’s address, and initialed with the value in DLL.

Here is the explanation from the book:

Once a DLL's file image is mapped into the calling process' address space, the DLL's functions are available to all the threads running within the process. When a thread calls a DLL function, the DLL function looks at the thread's stack to retrieve its passed parameters and uses the thread's stack for any local variables that it needs. In addition, any objects created by code in the DLL's functions are owned by the calling thread or process—a DLL never owns anything.

When one process maps a DLL image file into its address space, the system creates instances of the global and static data variables as well. (Though it doesn’t explicitly say the global data are create in process’s address.)

And following is another interesting question: what about two DLLs contain the same function?

As the testing result, when link two DLLs containing the same function name In the Visual C++, the compiler won’t report error, but call the function from the first DLL that linked to.

Actually the compiler needs to know which .lib file to link. And you may set the project dependencies to tell the compiler which .lib file to link. And you may also use #pragma comment (lib, ".//debug//myDll.lib"), and the third way is to set input in the link setting.

 

In the book it’s also reminds that avoid exporting variables

In real life, you should avoid exporting variables because this removes a level of abstraction in your code and makes it more difficult to maintain your DLL's code.

In addition, C++ classes can be exported only if the modules importing the C++ class are compiled using a compiler from the same vendor. For this reason, you should also avoid exporting C++ classes unless you know that the executable module developers use the same tools as the DLL module developers.

### 如何在ATL DLL中实现共享内存 #### 创建命名映射文件对象 为了使不同进程能够访问同一块共享内存,在创建共享内存之前,需先建立一个具有唯一名称的文件映射对象。这可以通过`CreateFileMapping()` API 函数完成[^1]。 ```cpp HANDLE hMapFile; hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, // 使用分页池 NULL, // 默认的安全属性 PAGE_READWRITE, // 读写权限 0, BUF_SIZE, szName); // 映射对象的名字 if (hMapFile == NULL) { _tprintf(TEXT("Could not create file mapping object (%d).\n"), GetLastError()); } ``` #### 获取指向共享内存区域的指针 一旦成功建立了文件映射对象,则可通过 `MapViewOfFile()` 来获取一块可操作的视图地址,即实际用于存储数据的空间位置[^2]。 ```cpp LPCTSTR pBuf; pBuf = (LPTSTR) MapViewOfFile(hMapFile, // 文件映射句柄 FILE_MAP_ALL_ACCESS, // 完全存取权 0, 0, BUF_SIZE); if (pBuf == NULL) { _tprintf(TEXT("Could not map view of file (%d).\n"), GetLastError()); CloseHandle(hMapFile); } // 将要传递的数据复制到缓冲区中... CopyMemory((PVOID)pBuf, buf, (_tcslen(buf) + 1) * sizeof(TCHAR)); ``` #### 实现线程同步机制 为了避免多个进程同时修改相同部分造成冲突,通常还需要引入互斥体(mutexes),事件(events), 或信号量(semaphores)等同步原语来协调各进程间的协作行为[^3]。 ```cpp // 声明并初始化互斥变量 HANDLE hMutex; hMutex = CreateMutex(NULL, FALSE, TEXT("Global\\MySharedMemMutex")); if (GetLastError() == ERROR_ALREADY_EXISTS){ // 如果已经存在则打开现有的互斥锁 }else { // 否则新建一个互斥锁 } WaitForSingleObject(hMutex, INFINITE); // 执行临界区内的代码... ReleaseMutex(hMutex); CloseHandle(hMutex); ``` 以上就是在 ATL DLL 中利用 Windows 提供的标准API实现了基本的共享内存功能。需要注意的是,当涉及到跨平台开发时,应当考虑兼容性和移植性问题;另外也要注意资源释放以及异常处理等问题以确保系统的稳定性[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值