第一課:來源於_ Po學校
動態連接庫 c++
extern "C"//把c++函數轉換成c的方式 (也就是函數名不慘料)編程
概念 :windows
(窗口)
findwindow ---存在於 Uer32.dll
kernel32.dll (內核)函數
當代碼用到dll的時候 用它的copy指向 達到節約內存操作系統
dll是一個能被其餘程序加載的程序 (如可讓QQ加載本身寫的dll)
操做系統對任何的動態連接庫,只會保存一份 (修改將會是全局的)線程
dll能進行動態調節、動態進行加載指針
/////////////調試
Dllmain //打破只能被調用的命運,今後掌握主動大權
主動:
case DLL_PROCESS_ATTACH: //被其餘程序加載的時候
case DLL_THREAD_ATTACH: //當其餘程序有新線程啓動的時候
case DLL_THREAD_DETACH: //當其餘程序某個線程終止(卸載)的時候
case DLL_PROCESS_DETACH: //被其餘程序卸載code
因爲ascii不能表示中文,因此就有了unicode,utf-8之類的多字節的字符 L宏就是把ascii的字符串轉成多字節的。視頻
MessageBox(NULL, L"DLL被加載!被線程加載", L"I Love..!", MB_OK); //這句是建立小對話框的
由於dll只能被其餘程序加載, 因此不能直接按F5調試 或設爲啓動項目便可
注意: //先找當前文件夾-》若是當前文件夾沒有-》咱們就去system32下查找-》64位 windows/system32 // 32位 windows/SysWoW64
360檢測不到SysWOW64
//user32.dll -> 若是我在他的本地文件裏創建一個假的user32.dll -》 他會不會加載這個假的dll
//這是DLL劫持 聽說之前用的不少
------------------
DLL導出函數 、 內部函數
DLL導出函數----》 新建一個項目 dll 勾選導出
加載裏面的int fnDllExportDemo(void)函數 HMODULE hModule=::LoadLibrary(L"DllExprotDemo.dll"); //加載的時候寫上名字就能夠了
使用fnDllExportDemo(void)函數的兩種方法:
=======================================================================================
1.動態連接---
typedef int(*FUNC)(void);//這是一個函數類型
先要知道它的原型:
//HMODULE至關於當前這個dll的身份證號 定位到dll上面 //L宏就是把ascii的字符串轉成多字節的。
HMODULE hModule=::LoadLibrary(L"DllExprotDemo.dll"); //加載的時候寫上名字就能夠了
//先找當前文件夾-》若是當前文件夾沒有-》咱們就去system32下查找-》64位 windows/system32 // 32位 windows/SysWoW64
if (hModule == NULL) //當加載不到dll的時候 hModule的值會爲空
{
MessageBox(NULL, L"加載DLL失敗!", L"I Love mark!",MB_OK);
}
FUNC dllFunc=(FUNC)::GetProcAddress(hModule, "fnDllExprotDemo");//使用windows的API:GetProcAddress 得到句柄(把要使用的函數名傳進去 會返回一個指針,用剛定義的接住),強轉
printf("%d", dllFunc()); //調用 :好比printf 跟普通函數一毛同樣
//當前使用的是c++編譯出來的, 它有一個命名粉碎機制
//也就是 c++支持重載,它將你全部的函數名稱都加點料
//要使用 得用c的方式進行編譯 在
//DLLEXPROTDEMO_API int fnDllExprotDemo(void); //(DLLEXPROTDEMO_H目錄下)
//更改爲:
extern "C" DLLEXPROTDEMO_API int fnDllExprotDemo(void);
========================================================================================
2.靜態連接---
1.拷貝它的頭文件 ,放在要使用它的工程下面 (當前的也就是LoadDllDemo)
2.拷貝它的.lib ,也放在要使用它的工程下面
3.包含頭文件 #include"DllExportDemo.h" #pragma comment(lib,"DllExportDemo.lib")
而後就能夠直接調用了 printf("%d",fnDllExportDemo());
typedef int(*FUNC)(void);//這是一個函數類型
//當前使用的是c++編譯出來的, 它有一個命名粉碎機制
//也就是 c++支持重載,它將你全部的函數名稱都加點料
//要使用 得用c的方式進行編譯 在
//DLLEXPROTDEMO_API int fnDllExprotDemo(void);
//更改爲:
extern "C" DLLEXPROTDEMO_API int fnDllExprotDemo(void);
------------------------------------------------------------------------------------------------
CreateProcess function //建立進程函數
-----
//當前使用的是c++編譯出來的, 它有一個命名粉碎機制
//也就是 c++支持重載,它將你全部的函數名稱都加點料
//要使用 得用c的方式進行編譯 在
//DLLEXPROTDEMO_API int fnDllExprotDemo(void);
//更改爲:
extern "C" DLLEXPROTDEMO_API int fnDllExprotDemo(void);
---------------------------------
小結:導出函數 不管用哪一種方式 都要用extern "C"方式編譯
extern"C" EXPORTDLL_API int fnExportDll(void); //c模式 #include "stdafx.h" #include<Windows.h> #include"ExportDll.h" #pragma comment(lib,"ExportDll.lib") typedef int(*FUNC)(void); // int main() { //HMODULE hModule = ::LoadLibrary(L"Practicedll_1.dll"); //加載 (這個呢,是沒有導出的) HMODULE hModule=::LoadLibrary(L"ExportDll.dll"); //加載 (導出的) if (hModule == NULL) { MessageBox(NULL, L"加載失敗", L"Mark", MB_OK); } //printf("%d", fnExportDll()); //靜態導出的 (.h 和lib拷貝到執行程序下) //********如下是動態連接 FUNC dllFunc = (FUNC)::GetProcAddress(hModule, "fnExportDll");// 使用windows的API:GetProcAddress 得到句柄 (會返回一個指針) printf("%d", dllFunc()); return 0; }
感謝鹿鳴老師,還有Linda老師 ,還有Mark老師課講得很是好 通俗易懂並且很是詳細!
歡迎加 c++討論羣484983958 免費領視頻哦 來 編程/黑客 愛好者