本节内容

  • 1、如何从DLL中获得资源(MFC DLL)
  • 2、如何使用DEF文件导出函数
  • 3、如何显式链接DLL
  • 4、如何隐式链接DLL
  • 5、如何在DLL中共享数据
  • 6、如何在DLL中使用对话框资源(MFC DLL)
  • 7、如何在MFC扩展DLL中导出类
  • 8、DLL文件路径
    • 8.1 方式一、采用LoadLibraryEx
    • 8.2 方式二、采用SetCurrentDir
    • 8.3 dll的加载顺序总结
    • 8.4 LoadLibraryEx函数参数说明
  • 9、DLL文件相关函数
  • 10、示例说明
    • 10.1 在dll文件内定义函数
    • 10.2 静态加载(Using Load-Time Dynamic Linking)
    • 10.3 动态加载(Using Run-Time Dynamic Linking)
  • 结语

Stands for “Dynamic Link Library.” A DLL (.dll) file contains a library of functions and other information that can be accessed by a Windows program. When a program is launched, links to the necessary .dll files are created. If a static link is created, the .dll files will be in use as long as the program is active. If a dynamic link is created, the .dll files will only be used when needed. Dynamic links help programs use resources, such as memory and hard drive space, more efficiently.

1、如何从DLL中获得资源(MFC DLL)

LoadLibrary+::LoadString/::LoadIcon/::LoadBitmap

    HINSTANCE hModule = LoadLibrary(_T("test.dll"));HBITMAP hBitmap = LoadBitmap(hModule,MAKEINTRESOURCE(1002));if (hBitmap != NULL){//设置位图CBitmap bmp;bmp.Attach(hBitmap);CRect rect;GetClientRect(rect);CDC* pDC = GetDC();CDC memDC;memDC.CreateCompatibleDC(pDC);memDC.SelectObject(&bmp);pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);bmp.Detach();memDC.DeleteDC();}

2、如何使用DEF文件导出函数

int fnTest(void);

如何使用关键字_declspec (dllexport)导出函数

#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
extern "C" TEST_API int fnTest(void);

3、如何显式链接DLL

//加载DLLHINSTANCE hModule = LoadLibrary(_T("test.dll"));if (hModule == NULL) return;typedef int (_cdecl *FUNTEST)(void);FUNTEST pfnTest;//获得导出函数的地址pfnTest = (FUNTEST)GetProcAddress(hModule, "fnTest");//调用导出函数if (pfnTest != NULL){int nValue = (*pfnTest)();CString strMessage = _T("");strMessage.Format(_T("%d"), nValue);AfxMessageBox(strMessage);}else{int n = GetLastError();TRACE(_T("LastError:%d\n"), n);   }//释放DLLFreeLibrary(hModule);

4、如何隐式链接DLL

//DLL导出函数的头文件
#include "Test.h"
//DLL的导入库lib文件
#pragma comment(lib, "test.lib")
//直接调用DLL的导出函数
int nValue = fnTest();

5、如何在DLL中共享数据

#pragma data_seg(".SharedData")
int nCount = 0;
#pragma data_seg()
int GetCount(){return nCount;
}
EXPORTS:    GetCount
SECTIONS:   .SharedData SHARED
//DLL导出函数的头文件
#include "Test.h"
//DLL的导入库lib文件
#pragma comment(lib, "test.lib")
int nCount = GetCount();

6、如何在DLL中使用对话框资源(MFC DLL)

//改变模块的状态
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg dlg;
dlg.DoModal();
//DLL的导入库lib文件
#pragma comment(lib, "test.lib")
void ShowDialog();

7、如何在MFC扩展DLL中导出类

#include "ExtClass.h"
#include "DeskTopTool.h"
//DLL的导入库lib文件
#pragma comment(lib, "test.lib")
……CExtClass ExtClass;ExtClass.Test();

8、DLL文件路径

Dynamic-Link Library Search Order

8.1 方式一、采用LoadLibraryEx

若DLL不在调用方的同一目录下,可以用LoadLibrary(L"DLL绝对路径")加载。但若调用的DLL内部又调用另外一个DLL,此时调用仍会失败。解决办法是用LoadLibraryEx:

LoadLibraryEx("DLL绝对路径", NULL,LOAD_WITH_ALTERED_SEARCH_PATH);

通过指定LOAD_WITH_ALTERED_SEARCH_PATH,让系统DLL搜索顺序从DLL所在目录开始。

8.2 方式二、采用SetCurrentDir

跨目录调用dll,你应该这样
1 用GetCurrentDir保存当前的工作目录
2 用SetCurrentDir将当前的工作目录,设置为你的DLL所在的路径,需要使用绝对路径
3 用LoadLibrary你的DLL
4 使用SetCurrentDir恢复到原来的工作路径

TCHAR chCurDir[MAX_PATH] = {0};
GetCurrentDirectory(MAX_PATH, chCurDir);
SetCurrentDirectory(_T("E:\\test\\"));
m_hDLL = LoadLibrary(_T("MyTest.dll"));
SetCurrentDirectory(chCurDir);

8.3 dll的加载顺序总结

  1. EXE所在目录;
  2. 当前目录GetCurrentDirectory();
  3. 系统目录GetSystemDirectory();
  4. WINDOWS目录GetWindowsDirectory();
  5. 环境变量 PATH 所包含的目录。

所以使用loadlibrary加载dll使用的路径,但是这个函数会忽略这个路径,只会按既定规则加载dll。所以如果要加载指定目录的dll,可以用上述两个解决方案。

8.4 LoadLibraryEx函数参数说明

LoadLibraryExA function

HMODULE LoadLibraryExA([in] LPCSTR lpLibFileName,HANDLE hFile,[in] DWORD  dwFlags
);
//Load the FMAPI DLL
hLib = ::LoadLibraryEx(L"fmapi.dll", NULL, NULL);
if ( !hLib )
{wprintf(L"Could not load fmapi.dll, Error #%d.\n", GetLastError());return;
}

LoadLibraryEx装载指定的动态链接库,并为当前进程把它映射到地址空间。一旦载入,就可以访问库内保存的资源。

  1. 它的返回值,Long,成功则返回库模块的句柄,零表示失败。会设置GetLastError。
    它的参数类型及说明如下:

  2. lpLibFileName String,指定要载入的动态链接库的名称。采用与CreateProcess函数的lpCommandLine参数指定的同样的搜索顺序。

  3. hFile Long,未用,设为零。

  4. dwFlags Long,指定下述常数的一个或多个:
    (1)DONT_RESOLVE_DLL_REFERENCES:不对DLL进行初始化,仅用于NT
    (2)LOAD_LIBRARY_AS_DATAFILE:不准备DLL执行。如装载一个DLL只是为了访问它的资源,就可以改善一部分性能
    (3)LOAD_WITH_ALTERED_SEARCH_PATH:指定搜索的路径

9、DLL文件相关函数

Dynamic-Link Library Functions

Function Description
AddDllDirectory Adds a directory to the process DLL search path.
DisableThreadLibraryCalls Disables thread attach and thread detach notifications for the specified DLL.
DllMain An optional entry point into a DLL.
FreeLibrary Decrements the reference count of the loaded DLL. When the reference count reaches zero, the module is unmapped from the address space of the calling process.
FreeLibraryAndExitThread Decrements the reference count of a loaded DLL by one, and then calls ExitThread to terminate the calling thread.
GetDllDirectory Retrieves the application-specific portion of the search path used to locate DLLs for the application.
GetModuleFileName Retrieves the fully qualified path for the file containing the specified module.
GetModuleFileNameEx Retrieves the fully qualified path for the file containing the specified module.
GetModuleHandle Retrieves a module handle for the specified module.
GetModuleHandleEx Retrieves a module handle for the specified module.
GetProcAddress Retrieves the address of an exported function or variable from the specified DLL.
LoadLibrary Maps the specified executable module into the address space of the calling process.
LoadLibraryEx Maps the specified executable module into the address space of the calling process.
LoadPackagedLibrary Maps the specified packaged module and its dependencies into the address space of the calling process. Only Windows Store apps can call this function.
RemoveDllDirectory Removes a directory that was added to the process DLL search path by using AddDllDirectory.
SetDefaultDllDirectories Specifies a default set of directories to search when the calling process loads a DLL.
SetDllDirectory Modifies the search path used to locate DLLs for the application.

10、示例说明

Creating a Simple Dynamic-Link Library

10.1 在dll文件内定义函数

#include <windows.h>
#define EOF (-1)#ifdef __cplusplus    // If used by C++ code,
extern "C" {          // we need to export the C interface
#endif__declspec(dllexport) int __cdecl myPuts(LPWSTR lpszMsg)
{DWORD cchWritten;HANDLE hConout;BOOL fRet;// Get a handle to the console output device.hConout = CreateFileW(L"CONOUT$",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if (INVALID_HANDLE_VALUE == hConout)return EOF;// Write a null-terminated string to the console output device.while (*lpszMsg != L'\0'){fRet = WriteConsole(hConout, lpszMsg, 1, &cchWritten, NULL);if( (FALSE == fRet) || (1 != cchWritten) )return EOF;lpszMsg++;}return 1;
}#ifdef __cplusplus
}
#endif

10.2 静态加载(Using Load-Time Dynamic Linking)

#include <windows.h> extern "C" int __cdecl myPuts(LPWSTR);   // a function from a DLLint main(VOID)
{ int Ret = 1;Ret = myPuts(L"Message sent to the DLL function\n"); return Ret;
}

10.3 动态加载(Using Run-Time Dynamic Linking)

#include <windows.h>
#include <stdio.h> typedef int (__cdecl *MYPROC)(LPWSTR); int main( void )
{ HINSTANCE hinstLib; MYPROC ProcAdd; BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; // Get a handle to the DLL module.hinstLib = LoadLibrary(TEXT("MyPuts.dll")); // If the handle is valid, try to get the function address.if (hinstLib != NULL) { ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts"); // If the function address is valid, call the function.if (NULL != ProcAdd) {fRunTimeLinkSuccess = TRUE;(ProcAdd) (L"Message sent to the DLL function\n"); }// Free the DLL module.fFreeResult = FreeLibrary(hinstLib); } // If unable to call the DLL function, use an alternative.if (! fRunTimeLinkSuccess) printf("Message printed from executable\n"); return 0;}

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

C++动态链接库DLL文件的加载相关推荐

  1. java web配置dll文件_JavaWeb项目中dll文件动态加载方法解析(详细步骤)

    相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO ...

  2. dll文件懒加载_dll编写与使用操作手册

    一写dll需要建立至少三个文件: 1 .cpp文件用于写核心代码. 里面包括一个dll入口函数DllMain.形如: 包括需要导出的变量和函数,图中的是add.以及不需要导出的变量和函数. 2 .h文 ...

  3. dll文件懒加载_一步步学习NHibernate(5)——多对一,一对多,懒加载(2)

    请注明转载地址:http://www.cnblogs.com/arhat 通过上一章的学习,我们建立了Student和Clazz之间的关联属性,并从Student(many)的一方查看了Clazz的信 ...

  4. dll文件懒加载_前端性能优化

    # 前端性能优化 写在最前面:下面都是我对webpack的一些性能优化,想系统的学习性能优化方面的知识 推荐大家看看这本书 很系统 感觉面试也能如鱼得水 ## 构建优化 ### webpack优化 ( ...

  5. 在VC++中创建DLL文件并加载

    一.Win32动态链接库 1.制作的步骤: (1)新建WIN32 Dynamic-link Library工程,工程名为MyDll,选择A DLL that export some symbol (s ...

  6. Qt如何调用VS编写的动态链接库(dll文件)

    在最近的开发中需要做了demo,来验证公司的老项目能否在Qt上做重新开发:于是碰到的第一个问题那就是dll文件如何加载了:网上查阅了很多资料,记录一下已成功加载dll文件的方法,以防遗忘. 下面是我在 ...

  7. 静态链接库(LIB)和动态链接库(DLL),DLL的静态加载和动态加载,两种LIB文件。

    静态链接库(LIB)和动态链接库(DLL),DLL的静态加载和动态加载,两种LIB文件. 一. 静态链接库(LIB,也简称"静态库")与动态链接库(DLL,也简称"动态库 ...

  8. VB 文件未找到: 'C:\WINDOWS\system32\ieframe.dll\1'--继续加载工程吗?

    引用:http://blog.sina.com.cn/s/blog_5542b9c90100xsm8.html 文件未找到: 'C:\WINDOWS\system32\ieframe.dll\1'-- ...

  9. 认识动态链接库DLL文件(转一篇文章)

    认识动态链接库DLL文件[url]http://bbs.pcpro.com.cn/viewthread.php?tid=10040[/url] DLL文件即动态链接库文件,是一种可执行文件,它允许程序 ...

最新文章

  1. js事件触发器fireEvent和dispatchEvent
  2. Apache中Virtual Host虚拟主机配置及rewrite参数说明
  3. 在coursera上有哪些值得推荐的课程
  4. 会议 | 2018年全国知识图谱与语义计算大会(CCKS 2018)
  5. 利用 html 和 css 实现导航栏下拉(display block、display none)
  6. maven打的包带exec包比不带的大_spring boot maven打包可执行jar包缺少依赖包的问题...
  7. c#软件操作-cmd命令全解
  8. Atitit 图像处理知识点  知识体系 知识图谱
  9. popWindow回传方法
  10. 计算机系统u盘判断,U盘真实容量检测工具
  11. 数据结构(一)线性链表、非线性链表、稀疏数组与队列、单向链表
  12. 做课题与科研项目常用的研究方法
  13. oracle 同义词表结构,Oracle 数据库的同义词+视图
  14. 解决微软的反盗版补丁
  15. 实名认证-身份证实名认证-身份证实名认证接口-身份证实名认证api-实名认证api接口-身份证实名认证api接口
  16. 如何成为一个 IT 界的女装大佬?
  17. 赶紧学会!开发者愚人节怎么写代码。。。
  18. 电容滤波电路电感滤波电路作用原理
  19. 编程之美2013年大赛解题思路--初赛(A)
  20. Markdown学习规划

热门文章

  1. 数据结构——整数算数表达式
  2. DOM替换replaceWith()和replaceAll() 之前学习了节点的内插入、外插入以及删除方法,这节会学习替换方法replaceWith .replaceWith( newConten
  3. html下拉列表默认未选择,Html.DropdownListFor未设置选定值
  4. Window下为文件名加前缀
  5. 马斯克光环下的 PayPal,枪口对准微信、支付宝?
  6. Canvas实现微信红包照片效果
  7. Mac电脑tomcat安装部署
  8. FORTRAN+计算物理学学习日记(1)
  9. 蓝桥杯合数求和题解C++
  10. 后悔升级iPhone?教你如何把iOS15降回iOS14