700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > C++动态链接库DLL文件的加载

C++动态链接库DLL文件的加载

时间:2024-04-18 23:27:37

相关推荐

C++动态链接库DLL文件的加载

本节内容

1、如何从DLL中获得资源(MFC DLL)2、如何使用DEF文件导出函数3、如何显式链接DLL4、如何隐式链接DLL5、如何在DLL中共享数据6、如何在DLL中使用对话框资源(MFC DLL)7、如何在MFC扩展DLL中导出类8、DLL文件路径8.1 方式一、采用LoadLibraryEx8.2 方式二、采用SetCurrentDir8.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)#endifextern "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:GetCountSECTIONS:.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的加载顺序总结

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

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

8.4 LoadLibraryEx函数参数说明

LoadLibraryExA function

HMODULE LoadLibraryExA([in] LPCSTR lpLibFileName,HANDLE hFile,[in] DWORD dwFlags);

//Load the FMAPI DLLhLib = ::LoadLibraryEx(L"fmapi.dll", NULL, NULL); if ( !hLib ){wprintf(L"Could not load fmapi.dll, Error #%d.\n", GetLastError());return;}

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

它的返回值,Long,成功则返回库模块的句柄,零表示失败。会设置GetLastError。

它的参数类型及说明如下:

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

hFile Long,未用,设为零。

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

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???

如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)

感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。