赞
踩
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.
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();
}
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);
//加载DLL
HINSTANCE 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);
}
//释放DLL
FreeLibrary(hModule);
//DLL导出函数的头文件
#include "Test.h"
//DLL的导入库lib文件
#pragma comment(lib, "test.lib")
//直接调用DLL的导出函数
int nValue = fnTest();
#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();
//改变模块的状态
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CTestDlg dlg;
dlg.DoModal();
//DLL的导入库lib文件
#pragma comment(lib, "test.lib")
void ShowDialog();
#include "ExtClass.h"
#include "DeskTopTool.h"
//DLL的导入库lib文件
#pragma comment(lib, "test.lib")
……
CExtClass ExtClass;
ExtClass.Test();
Dynamic-Link Library Search Order
若DLL不在调用方的同一目录下,可以用LoadLibrary(L"DLL绝对路径")加载。但若调用的DLL内部又调用另外一个DLL,此时调用仍会失败。解决办法是用LoadLibraryEx:
LoadLibraryEx("DLL绝对路径", NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
通过指定LOAD_WITH_ALTERED_SEARCH_PATH,让系统DLL搜索顺序从DLL所在目录开始。
跨目录调用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);
所以使用loadlibrary加载dll使用的路径,但是这个函数会忽略这个路径,只会按既定规则加载dll。所以如果要加载指定目录的dll,可以用上述两个解决方案。
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装载指定的动态链接库,并为当前进程把它映射到地址空间。一旦载入,就可以访问库内保存的资源。
它的返回值,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:指定搜索的路径
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. |
Creating a Simple Dynamic-Link Library
#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
#include <windows.h>
extern "C" int __cdecl myPuts(LPWSTR); // a function from a DLL
int main(VOID)
{
int Ret = 1;
Ret = myPuts(L"Message sent to the DLL function\n");
return Ret;
}
#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???
如果您需要相关功能的代码定制化开发,可以留言私信作者;
(✿◡‿◡)
感谢各位童鞋们的支持!
( ´ ▽´ )ノ ( ´ ▽´)っ!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。