1、typedef int (WINAPI* LPSDOLInitialize)(const SDOLAppInfo* pAppInfo)
在 C/C++ 中,typedef 用于創(chuàng)建類型別名,它可以讓你為一個(gè)已有的數(shù)據(jù)類型定義一個(gè)新的名稱,從而使代碼更加清晰、易讀,也可以簡化類型的聲明和使用。
這段代碼用typedef定義了一個(gè)函數(shù)指針類型 LPSDOLInitialize,該函數(shù)指針指向一個(gè)函數(shù),該函數(shù)接受一個(gè)指向 SDOLAppInfo 結(jié)構(gòu)體的指針作為參數(shù),并返回一個(gè) int 類型的值。
具體來說,typedef 是用于創(chuàng)建類型別名的關(guān)鍵字。在這里,它創(chuàng)建了一個(gè)名為 LPSDOLInitialize 的新類型,它被定義為一個(gè)函數(shù)指針類型,該函數(shù)指針指向具有特定參數(shù)和返回類型的函數(shù)。
WINAPI 是一個(gè)宏,用于指定函數(shù)的調(diào)用約定,它在 Windows 平臺上用于標(biāo)識函數(shù)調(diào)用的方式和參數(shù)傳遞方式。
總結(jié)一下,該代碼段定義了一個(gè)函數(shù)指針類型 LPSDOLInitialize,該指針可以指向一個(gè)具有特定參數(shù)和返回類型的函數(shù),這個(gè)函數(shù)接受一個(gè)指向 SDOLAppInfo 結(jié)構(gòu)體的指針作為參數(shù),并返回一個(gè) int 類型的值。這種函數(shù)指針的定義通常用于在運(yùn)行時(shí)動態(tài)加載庫中的函數(shù)并進(jìn)行調(diào)用。
用這個(gè)函數(shù)指針類型 LPSDOLInitialize就可以創(chuàng)建對象: LLPSDOLInitialize m_pfSDOLInitialize;
例如,假設(shè)你想要聲明一個(gè)函數(shù)指針變量來保存指向這樣一個(gè)函數(shù)的指針,你可以這樣寫:
LPSDOLInitialize pFuncPointer;
這使得代碼更加簡潔,而不是每次都寫完整的函數(shù)指針類型。typedef 在這里的作用就是為了創(chuàng)建一個(gè)新的名稱,使代碼更具可讀性。
//函數(shù)指針對象
if (m_pfSDOLInitialize(&appinfo) != SDOL_ERRORCODE_OK)
{
return false;
}
另外,typedef 還可以用于創(chuàng)建其他類型別名,如結(jié)構(gòu)體、枚舉等,以及用于更方便地處理復(fù)雜的數(shù)據(jù)類型。
2、typedef int (WINAPI* LPSDOLGetModule)(REFIID riid, void** intf)
這個(gè) typedef 定義了另一個(gè)函數(shù)指針類型的別名 LPSDOLGetModule。這個(gè)函數(shù)指針指向一個(gè)具有以下特征的函數(shù):
- 返回類型為 int。
- 使用 WINAPI 調(diào)用約定。
- 接受一個(gè) REFIID 類型的參數(shù) riid 和一個(gè) void** 類型的參數(shù) intf。
3、typedef int (WINAPI* LPSDOLTerminal)();
這個(gè) typedef 定義了第三個(gè)函數(shù)指針類型的別名 LPSDOLTerminal。這個(gè)函數(shù)指針指向一個(gè)具有以下特征的函數(shù):
- 返回類型為 int。
- 使用 WINAPI 調(diào)用約定。
- 不接受任何參數(shù)。
為什么要使用 typedef 呢?使用 typedef 可以讓代碼更加清晰,提高可讀性。通過定義這些函數(shù)指針類型的別名,可以更容易地聲明和使用這些函數(shù)指針,特別是在涉及到多次使用相同函數(shù)指針類型的情況下。這有助于簡化代碼并提高可維護(hù)性。
4、GetProcAddress運(yùn)行時(shí)獲取一個(gè)動態(tài)鏈接庫(DLL)中導(dǎo)出函數(shù)的地址
WINBASEAPI
FARPROC
WINAPI
GetProcAddress (
__in HMODULE hModule,
__in LPCSTR lpProcName
);
這段代碼片段是 Windows 操作系統(tǒng)的頭文件和函數(shù)聲明。讓我為您解釋一下這些概念:
-
WINBASEAPI: 這是一個(gè)宏,通常用于聲明 Windows API 函數(shù)。它在 Windows 頭文件中定義,并根據(jù)編譯器和系統(tǒng)的不同進(jìn)行設(shè)置。它的作用是為了確保在編譯時(shí)使用正確的調(diào)用約定(calling convention)和導(dǎo)入/導(dǎo)出修飾符。
-
FARPROC: 這是一個(gè)函數(shù)指針類型,用于指向?qū)霂旌瘮?shù)。FARPROC 代表 “FAR Procedure”,在 32 位 Windows 中用于指向動態(tài)鏈接庫(DLL)中的函數(shù)。
-
WINAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù),同時(shí)指定函數(shù)的調(diào)用約定。WINAPI 宏的定義會根據(jù)編譯器和系統(tǒng)的不同進(jìn)行設(shè)置。通常,它會將函數(shù)調(diào)用約定設(shè)置為 __stdcall,這是一種用于 Windows API 的常見調(diào)用約定。
-
GetProcAddress: 這是 Windows API 中的一個(gè)函數(shù),用于在運(yùn)行時(shí)獲取一個(gè)動態(tài)鏈接庫(DLL)中導(dǎo)出函數(shù)的地址。這個(gè)函數(shù)在加載 DLL 后用于獲取指定函數(shù)的指針,以便在程序中調(diào)用這些函數(shù)。
所以,這段代碼片段聲明了 GetProcAddress 函數(shù),并提供了它的參數(shù)類型和說明。在實(shí)際代碼中,您需要包含相關(guān)的 Windows 頭文件,并根據(jù)需要使用這個(gè)函數(shù)來獲取 DLL 中導(dǎo)出函數(shù)的指針,從而進(jìn)行調(diào)用。
GetProcAddress 是 Windows 操作系統(tǒng)提供的一個(gè)函數(shù),用于在運(yùn)行時(shí)獲取一個(gè)動態(tài)鏈接庫(DLL)中導(dǎo)出函數(shù)的地址。這個(gè)函數(shù)通常在動態(tài)鏈接庫加載后被調(diào)用,用于獲取庫中特定函數(shù)的指針,以便在程序中調(diào)用這些函數(shù)。
函數(shù)簽名如下:
FARPROC GetProcAddress(
HMODULE hModule, // 動態(tài)鏈接庫的句柄
LPCSTR lpProcName // 函數(shù)的名稱或者是函數(shù)的序號
);
-
hModule: 指向已加載的動態(tài)鏈接庫的句柄。通常使用 LoadLibrary 函數(shù)來加載動態(tài)鏈接庫,然后將返回的句柄傳遞給 GetProcAddress。
-
lpProcName: 要獲取地址的函數(shù)的名稱,或者是函數(shù)在導(dǎo)出表中的序號(函數(shù)的索引)。如果是名稱,應(yīng)該是一個(gè)以 NULL 結(jié)尾的字符串。
-
GetProcAddress 的返回值是一個(gè)函數(shù)指針,可以用于直接調(diào)用動態(tài)鏈接庫中的函數(shù)。這對于動態(tài)加載庫并在需要時(shí)使用其中的函數(shù)非常有用,特別是在插件式架構(gòu)中或者需要在運(yùn)行時(shí)決定調(diào)用哪些函數(shù)的情況下。
一個(gè)常見的用法是在加載插件時(shí)使用 GetProcAddress 來獲取插件中的函數(shù)指針,然后通過這些指針來調(diào)用插件中的功能。
5、LoadLibraryExA 用于加載指定ANSI的動態(tài)鏈接庫文件
WINBASEAPI
__out_opt
HMODULE
WINAPI
LoadLibraryExA(
__in LPCSTR lpLibFileName,
__reserved HANDLE hFile,
__in DWORD dwFlags
);
這段代碼是 Windows API 函數(shù) LoadLibraryExA 的聲明。讓我為您解釋一下其中的參數(shù)和類型:
-
WINBASEAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù)。它在 Windows 頭文件中定義,并根據(jù)編譯器和系統(tǒng)的不同進(jìn)行設(shè)置。
-
__out_opt: 這是一個(gè)標(biāo)記,表示函數(shù)的返回值可以是一個(gè)可選的輸出參數(shù)。在這個(gè)聲明中,它表示函數(shù)的返回值 HMODULE 可能會被用作輸出參數(shù),以傳遞一個(gè)返回的模塊句柄。
-
HMODULE: 這是一個(gè) Windows 數(shù)據(jù)類型,表示模塊(通常是 DLL 或 EXE)的句柄。HMODULE 句柄是用于在程序中引用已加載模塊的標(biāo)識符。
-
WINAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù),并指定函數(shù)的調(diào)用約定。通常情況下,它將函數(shù)調(diào)用約定設(shè)置為 __stdcall,這是一種用于 Windows API 的常見調(diào)用約定。
-
LoadLibraryExA: 這是一個(gè) Windows API 函數(shù),用于加載一個(gè)指定的動態(tài)鏈接庫(DLL)文件。
-
lpLibFileName: 一個(gè)以 null 結(jié)尾的字符串,表示要加載的 DLL 文件名。LPCSTR 表示一個(gè)指向以 ANSI 字符集編碼的字符串的指針。
-
hFile: 一個(gè)保留參數(shù),傳入 HANDLE 類型的文件句柄,或者傳入 NULL。
-
dwFlags: 一個(gè)標(biāo)志,用于指定加載 DLL 的方式??梢允歉鞣N標(biāo)志的組合,例如 :
- DONT_RESOLVE_DLL_REFERENCES: 加載 DLL 但不解析其依賴項(xiàng)。
- LOAD_LIBRARY_AS_DATAFILE: 將 DLL 視為數(shù)據(jù)文件而不是可執(zhí)行文件。
- LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: 僅在 DLL 所在的目錄中搜索依賴項(xiàng)。
綜合起來,這個(gè)聲明表明了一個(gè) Windows API 函數(shù) LoadLibraryExA,它用于加載指定的動態(tài)鏈接庫文件。函數(shù)返回一個(gè) HMODULE 類型的句柄,表示已加載的模塊。參數(shù)類型和標(biāo)記都提供了函數(shù)使用和返回值的相關(guān)信息。
6、LoadLibraryExW 用于加載指定Wide寬字符的動態(tài)鏈接庫文件
WINBASEAPI
__out_opt
HMODULE
WINAPI
LoadLibraryExW(
__in LPCWSTR lpLibFileName,
__reserved HANDLE hFile,
__in DWORD dwFlags
);
這段代碼是 Windows API 函數(shù) LoadLibraryExW 的聲明。讓我為您解釋一下其中的參數(shù)和類型:
-
WINBASEAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù)。它在 Windows 頭文件中定義,并根據(jù)編譯器和系統(tǒng)的不同進(jìn)行設(shè)置。
-
__out_opt: 這是一個(gè)標(biāo)記,表示函數(shù)的返回值可以是一個(gè)可選的輸出參數(shù)。在這個(gè)聲明中,它表示函數(shù)的返回值 HMODULE 可能會被用作輸出參數(shù),以傳遞一個(gè)返回的模塊句柄。
-
HMODULE: 這是一個(gè) Windows 數(shù)據(jù)類型,表示模塊(通常是 DLL 或 EXE)的句柄。HMODULE 句柄是用于在程序中引用已加載模塊的標(biāo)識符。
-
WINAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù),并指定函數(shù)的調(diào)用約定。通常情況下,它將函數(shù)調(diào)用約定設(shè)置為 __stdcall,這是一種用于 Windows API 的常見調(diào)用約定。
-
LoadLibraryExW: 這是一個(gè) Windows API 函數(shù),用于加載一個(gè)指定的動態(tài)鏈接庫(DLL)文件。
-
lpLibFileName: 這是一個(gè)指向以 null 結(jié)尾的字符串的指針,表示要加載的動態(tài)鏈接庫(DLL)的文件名。LPCWSTR 表示一個(gè)指向以寬字符(Unicode)編碼的字符串的指針。您需要將要加載的 DLL 的文件名以寬字符格式傳遞給這個(gè)參數(shù)。
-
hFile: 一個(gè)保留參數(shù),傳入 HANDLE 類型的文件句柄,或者傳入 NULL。
-
dwFlags: 一個(gè)標(biāo)志,用于指定加載 DLL 的方式。可以是各種標(biāo)志的組合,例如 :
- DONT_RESOLVE_DLL_REFERENCES: 加載 DLL 但不解析其依賴項(xiàng)。
- LOAD_LIBRARY_AS_DATAFILE: 將 DLL 視為數(shù)據(jù)文件而不是可執(zhí)行文件。
- LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR: 僅在 DLL 所在的目錄中搜索依賴項(xiàng)。
綜合起來,LoadLibraryExW 函數(shù)用于加載指定的 DLL 文件,并且通過參數(shù)來控制加載方式和行為。根據(jù)傳遞的文件名、文件句柄和標(biāo)志,該函數(shù)將加載 DLL 并返回一個(gè)模塊句柄(HMODULE),以便后續(xù)操作使用。不同之處在于該函數(shù)接受寬字符格式的文件名,適用于 Unicode 編碼。
7、LoadLibraryA 用于加載指定ANSI的動態(tài)鏈接庫文件
WINBASEAPI
__out_opt
HMODULE
WINAPI
LoadLibraryExA(
__in LPCSTR lpLibFileName,
);
這段代碼是 Windows API 函數(shù) LoadLibraryA 的聲明。讓我為您解釋一下其中的參數(shù)和類型:
-
WINBASEAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù)。它在 Windows 頭文件中定義,并根據(jù)編譯器和系統(tǒng)的不同進(jìn)行設(shè)置。
-
__out_opt: 這是一個(gè)標(biāo)記,表示函數(shù)的返回值可以是一個(gè)可選的輸出參數(shù)。在這個(gè)聲明中,它表示函數(shù)的返回值 HMODULE 可能會被用作輸出參數(shù),以傳遞一個(gè)返回的模塊句柄。
-
HMODULE: 這是一個(gè) Windows 數(shù)據(jù)類型,表示模塊(通常是 DLL 或 EXE)的句柄。HMODULE 句柄是用于在程序中引用已加載模塊的標(biāo)識符。
-
WINAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù),并指定函數(shù)的調(diào)用約定。通常情況下,它將函數(shù)調(diào)用約定設(shè)置為 __stdcall,這是一種用于 Windows API 的常見調(diào)用約定。
-
LoadLibraryA: 這是一個(gè) Windows API 函數(shù),用于加載一個(gè)指定的動態(tài)鏈接庫(DLL)文件。
-
lpLibFileName: 一個(gè)以 null 結(jié)尾的字符串,表示要加載的 DLL 文件名。LPCSTR 表示一個(gè)指向以 ANSI 字符集編碼的字符串的指針。
綜合起來,這個(gè)聲明表明了一個(gè) Windows API 函數(shù) LoadLibraryA,它用于加載指定的動態(tài)鏈接庫文件。函數(shù)返回一個(gè) HMODULE 類型的句柄,表示已加載的模塊。參數(shù)類型和標(biāo)記都提供了函數(shù)使用和返回值的相關(guān)信息。總之,這個(gè)函數(shù)原型定義了 LoadLibraryA 函數(shù)的簽名,它接受一個(gè)以多字節(jié)字符編碼的 DLL 文件名作為參數(shù),然后返回一個(gè)表示已加載模塊的句柄。使用這個(gè)句柄,您可以執(zhí)行與該模塊相關(guān)的操作。
8、LoadLibraryW 用于加載指定Wide寬字符的動態(tài)鏈接庫文件
WINBASEAPI
__out_opt
HMODULE
WINAPI
LoadLibraryExW(
__in LPCWSTR lpLibFileName,
);
這段代碼是 Windows API 函數(shù) LoadLibraryW 的聲明。讓我為您解釋一下其中的參數(shù)和類型:
-
WINBASEAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù)。它在 Windows 頭文件中定義,并根據(jù)編譯器和系統(tǒng)的不同進(jìn)行設(shè)置。
-
__out_opt: 這是一個(gè)標(biāo)記,表示函數(shù)的返回值可以是一個(gè)可選的輸出參數(shù)。在這個(gè)聲明中,它表示函數(shù)的返回值 HMODULE 可能會被用作輸出參數(shù),以傳遞一個(gè)返回的模塊句柄。
-
HMODULE: 這是一個(gè) Windows 數(shù)據(jù)類型,表示模塊(通常是 DLL 或 EXE)的句柄。HMODULE 句柄是用于在程序中引用已加載模塊的標(biāo)識符。
-
WINAPI: 這是一個(gè)宏,用于聲明 Windows API 函數(shù),并指定函數(shù)的調(diào)用約定。通常情況下,它將函數(shù)調(diào)用約定設(shè)置為 __stdcall,這是一種用于 Windows API 的常見調(diào)用約定。
-
LoadLibraryW: 這是一個(gè) Windows API 函數(shù),用于加載一個(gè)指定的動態(tài)鏈接庫(DLL)文件。
-
lpLibFileName: 這是一個(gè)指向以 null 結(jié)尾的字符串的指針,表示要加載的動態(tài)鏈接庫(DLL)的文件名。LPCWSTR 表示一個(gè)指向以寬字符(Unicode)編碼的字符串的指針。您需要將要加載的 DLL 的文件名以寬字符格式傳遞給這個(gè)參數(shù)。
綜合起來,LoadLibraryW 函數(shù)用于加載指定的 DLL 文件。根據(jù)傳遞的文件名、文件句柄和標(biāo)志,該函數(shù)將加載 DLL 并返回一個(gè)模塊句柄(HMODULE),以便后續(xù)操作使用。不同之處在于該函數(shù)接受寬字符格式的文件名,適用于 Unicode 編碼??傊@個(gè)函數(shù)原型定義了 LoadLibraryA 函數(shù)的簽名,它接受一個(gè)以Unicode編碼的 DLL 文件名作為參數(shù),然后返回一個(gè)表示已加載模塊的句柄。使用這個(gè)句柄,您可以執(zhí)行與該模塊相關(guān)的操作。
9、LoadLibraryExA和LoadLibraryA以及LoadLibraryExW和LoadLibraryW區(qū)別
這些函數(shù)是 Windows API 中用于加載動態(tài)鏈接庫 (DLL) 的函數(shù),主要區(qū)別在于它們支持的字符串類型和加載選項(xiàng):
-
LoadLibraryExA 和 LoadLibraryA:
- LoadLibraryExA:用于以 ANSI 編碼加載 DLL。它接受 ANSI 字符串作為參數(shù)。
- LoadLibraryA:也用于以 ANSI 編碼加載 DLL。與 LoadLibraryExA 類似,但沒有額外的加載選項(xiàng)。
這兩個(gè)函數(shù)的主要區(qū)別在于 LoadLibraryExA 支持額外的加載選項(xiàng),如指定加載行為和加載上下文等。而 LoadLibraryA 是基本的加載函數(shù),不提供這些選項(xiàng)。
-
LoadLibraryExW 和 LoadLibraryW:
- LoadLibraryExW:用于以 Unicode 編碼加載 DLL。它接受 Unicode 字符串作為參數(shù)。
- LoadLibraryW:也用于以 Unicode 編碼加載 DLL。與 LoadLibraryExW 類似,但沒有額外的加載選項(xiàng)。
這兩個(gè)函數(shù)的區(qū)別與前面所述的 ANSI 版本類似,LoadLibraryExW 支持額外的加載選項(xiàng),而 LoadLibraryW 是基本的加載函數(shù)。
在選擇使用哪個(gè)函數(shù)時(shí),您需要根據(jù)字符串的編碼和加載選項(xiàng)來決定。如果您使用的是 ANSI 字符串,可以選擇 LoadLibraryExA 或 LoadLibraryA。如果您使用的是 Unicode 字符串,可以選擇 LoadLibraryExW 或 LoadLibraryW。如果您需要額外的加載選項(xiàng),可以使用以 “Ex” 結(jié)尾的版本。
10、typedef函數(shù)聲明與實(shí)現(xiàn)的例子
10.1、函數(shù)定義
typedef int (WINAPI* LPSDOLInitialize)(const SDOLAppInfo* pAppInfo);
typedef int (WINAPI* LPSDOLGetModule)(REFIID riid, void** intf);
typedef int (WINAPI* LPSDOLTerminal)();
10.2、函數(shù)實(shí)現(xiàn)加載動態(tài)鏈接庫
bool Initial(){
WCHAR strExePath[MAX_PATH] = { 0 };
WCHAR strExeName[MAX_PATH] = { 0 };
WCHAR* strLastSlash = NULL;
GetModuleFileNameW(NULL, strExePath, MAX_PATH);
strExePath[MAX_PATH - 1] = 0;
strLastSlash = wcsrchr(strExePath, TEXT('\\'));
if (strLastSlash)
{ // 得到EXE所在路徑
StringCchCopyW(strExeName, MAX_PATH, &strLastSlash[1]);
*strLastSlash = 0;
strLastSlash = wcsrchr(strExeName, TEXT('.'));
if (strLastSlash)
*strLastSlash = 0;
}
WCHAR strGameWidgetDll[MAX_PATH] = { 0 };
#ifdef _WIN64
StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry64.dll", strExePath);
#else
StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry.dll", strExePath);
#endif
if (GetFileAttributesW(strGameWidgetDll) == 0xFFFFFFFF) {
return false;
}
// string strEntry;
//#ifdef _WIN64
// strEntry = PathHelper::GetFullPath("..\\sdologinentry64.dll");
//#else
// strEntry = PathHelper::GetFullPath("..\\sdologinentry.dll");
//#endif
m_hSDOLoginModule = ::LoadLibraryW(strGameWidgetDll);
if (m_hSDOLoginModule == nullptr)
{
return false;
}
//Out-of-game login interface
m_pfSDOLInitialize = (LPSDOLInitialize)GetProcAddress(m_hSDOLoginModule, "SDOLInitialize");
m_pfSDOLGetModule = (LPSDOLGetModule)GetProcAddress(m_hSDOLoginModule, "SDOLGetModule");
m_pfSDOLTerminal = (LPSDOLTerminal)GetProcAddress(m_hSDOLoginModule, "SDOLTerminal");
if (m_pfSDOLInitialize == nullptr || m_pfSDOLGetModule == nullptr) return false;
}
WCHAR strExePath[MAX_PATH] = { 0 };
WCHAR strExeName[MAX_PATH] = { 0 };
WCHAR* strLastSlash = NULL;
GetModuleFileNameW(NULL, strExePath, MAX_PATH);
strExePath[MAX_PATH - 1] = 0;
strLastSlash = wcsrchr(strExePath, TEXT(‘\’));
if (strLastSlash)
{ // 得到EXE所在路徑
StringCchCopyW(strExeName, MAX_PATH, &strLastSlash[1]);
*strLastSlash = 0;
strLastSlash = wcsrchr(strExeName, TEXT(‘.’));
if (strLastSlash)
*strLastSlash = 0;
}
WCHAR strGameWidgetDll[MAX_PATH] = { 0 };
#ifdef _WIN64
StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry64.dll", strExePath);
#else
StringCchPrintfW(strGameWidgetDll, MAX_PATH, L"%s\\sdo\\sdologinentry.dll", strExePath);
#endif
if (GetFileAttributesW(strGameWidgetDll) == 0xFFFFFFFF) {
return false;
}
// string strEntry;
//#ifdef _WIN64
// strEntry = PathHelper::GetFullPath("..\\sdologinentry64.dll");
//#else
// strEntry = PathHelper::GetFullPath("..\\sdologinentry.dll");
//#endif
m_hSDOLoginModule = ::LoadLibraryW(strGameWidgetDll);
if (m_hSDOLoginModule == nullptr)
{
return false;
}
代碼解釋:
- 獲取當(dāng)前執(zhí)行程序的路徑和名稱:
- 使用
GetModuleFileNameW
函數(shù)獲取當(dāng)前執(zhí)行程序**(.exe)**的路徑,并將其存儲在strExePath
中。 - 從
strExePath
中提取出執(zhí)行程序的名稱并存儲在strExeName
中。
- 使用
- 提取執(zhí)行程序所在目錄:
- 在
strExePath
中找到最后一個(gè)反斜杠 “” 的位置,然后將它替換為 NULL 終止字符以分隔目錄路徑和文件名。 - 如果存在文件擴(kuò)展名,也將其刪除,以便獲得純粹的目錄路徑。
- 在
- 根據(jù)當(dāng)前架構(gòu)構(gòu)造
strGameWidgetDll
的路徑:- 根據(jù)操作系統(tǒng)架構(gòu)(32位或64位),構(gòu)建
strGameWidgetDll
路徑,這是一個(gè)包含了 “sdologinentry.dll” 或 “sdologinentry64.dll” 的完整路徑。
- 根據(jù)操作系統(tǒng)架構(gòu)(32位或64位),構(gòu)建
- 檢查文件是否存在:
- 使用
GetFileAttributesW
函數(shù)檢查strGameWidgetDll
文件是否存在,如果文件不存在,就返回false
。
- 使用
- 加載動態(tài)鏈接庫(DLL):
- 使用
LoadLibraryW
函數(shù)加載strGameWidgetDll
指定的 DLL 文件。如果加載失敗,返回false
。
- 使用
這段代碼的目的是獲取并加載一個(gè)特定的 DLL,該 DLL 位于與當(dāng)前執(zhí)行程序相同的目錄下,根據(jù)操作系統(tǒng)架構(gòu)選擇加載 “sdologinentry.dll” 或 “sdologinentry64.dll”。如果加載成功,m_hSDOLoginModule
將包含該 DLL 的句柄,以便后續(xù)可以使用 GetProcAddress
來獲取其中的函數(shù)地址。如果有任何錯誤發(fā)生,函數(shù)將返回 false
。
m_pfSDOLInitialize = (LPSDOLInitialize)GetProcAddress(m_hSDOLoginModule, “SDOLInitialize”);
代碼解釋:
-
m_pfSDOLInitialize
是一個(gè)函數(shù)指針,它似乎被用來指向一個(gè)函數(shù),該函數(shù)的名稱是 “SDOLInitialize”,并且這個(gè)函數(shù)是從模塊m_hSDOLoginModule
中獲取的。這種情況通常用于動態(tài)鏈接庫(Dynamic Link Library,DLL)或共享庫中的函數(shù)調(diào)用。 - 一般來說,這段代碼的目的是將
m_pfSDOLInitialize
這個(gè)函數(shù)指針指向m_hSDOLoginModule
模塊中的 “SDOLInitialize” 函數(shù),而m_hSDOLoginModule
模塊是一個(gè)動態(tài)鏈接庫中函數(shù)調(diào)用,以便后續(xù)可以通過該函數(shù)指針來調(diào)用 “SDOLInitialize” 函數(shù),而不必直接鏈接到該函數(shù)的庫。這種方式通常用于在運(yùn)行時(shí)加載庫并調(diào)用其中的函數(shù),而不是在編譯時(shí)鏈接到庫。 - 在使用
m_pfSDOLInitialize
這個(gè)函數(shù)指針之前,你需要確保m_hSDOLoginModule
已經(jīng)成功加載,并且 “SDOLInitialize” 函數(shù)已經(jīng)在該模塊中找到。否則,使用該函數(shù)指針可能導(dǎo)致運(yùn)行時(shí)錯誤。
m_pfSDOLGetModule = (LPSDOLGetModule)GetProcAddress(m_hSDOLoginModule, “SDOLGetModule”);
代碼解釋:
- 定義了一個(gè)函數(shù)指針
m_pfSDOLGetModule
,并使用GetProcAddress
函數(shù)從m_hSDOLoginModule
模塊中獲取 “SDOLGetModule” 函數(shù)的地址,并將其分配給m_pfSDOLGetModule
。這意味著m_pfSDOLGetModule
現(xiàn)在指向了m_hSDOLoginModule
中的 “SDOLGetModule” 函數(shù)。 -
這種操作通常用于動態(tài)加載函數(shù),使你能夠在運(yùn)行時(shí)調(diào)用這些函數(shù),而無需在編譯時(shí)將其鏈接到代碼中。 在使用
m_pfSDOLGetModule
指向的函數(shù)之前,你需要確保m_hSDOLoginModule
已成功加載,并且 “SDOLGetModule” 函數(shù)確實(shí)存在于該模塊中,否則會導(dǎo)致運(yùn)行時(shí)錯誤。
m_pfSDOLTerminal = (LPSDOLTerminal)GetProcAddress(m_hSDOLoginModule, “SDOLTerminal”);
代碼解釋:文章來源地址http://www.zghlxwxcb.cn/news/detail-653963.html
- 定義了一個(gè)函數(shù)指針
m_pfSDOLTerminal
,并使用GetProcAddress
函數(shù)從m_hSDOLoginModule
模塊中獲取 “SDOLTerminal” 函數(shù)的地址,并將其分配給m_pfSDOLTerminal
。這樣,m_pfSDOLTerminal
現(xiàn)在指向了m_hSDOLoginModule
中的 “SDOLTerminal” 函數(shù)。 -
這種操作允許你在運(yùn)行時(shí)動態(tài)加載并調(diào)用 “SDOLTerminal” 函數(shù),而無需在編譯時(shí)將其鏈接到代碼中。 在使用
m_pfSDOLTerminal
指向的函數(shù)之前,確保m_hSDOLoginModule
已成功加載,且 “SDOLTerminal” 函數(shù)確實(shí)存在于該模塊中,以避免運(yùn)行時(shí)錯誤。這樣的方式通常用于插件系統(tǒng)或需要在運(yùn)行時(shí)加載不同模塊的應(yīng)用程序。
if (m_pfSDOLInitialize == nullptr || m_pfSDOLGetModule == nullptr) return false;
代碼解釋:
- 代碼檢查了
m_pfSDOLInitialize
和m_pfSDOLGetModule
這兩個(gè)函數(shù)指針是否為空指針(nullptr
)。如果其中任何一個(gè)為空,它返回false
,否則繼續(xù)執(zhí)行后續(xù)的操作。 - 這種檢查通常用于確保成功加載并獲取到所需的函數(shù)地址。如果在前面的
GetProcAddress
調(diào)用中,未能獲取到 “SDOLInitialize” 或 “SDOLGetModule” 函數(shù)的地址,這些函數(shù)指針將會是空指針。因此,通過檢查它們是否為空,你可以在繼續(xù)使用這些函數(shù)指針之前確保它們已成功獲取,以避免在嘗試調(diào)用這些函數(shù)時(shí)引發(fā)未定義行為或錯誤。 - 這是一種常見的做法,用于提高代碼的魯棒性,特別是在涉及動態(tài)加載函數(shù)的情況下。如果函數(shù)指針不為空,那么它們將指向有效的函數(shù),否則你可以選擇采取適當(dāng)?shù)腻e誤處理措施。
10.3、sdologinentry.dll或者sdologinentry64.dll動態(tài)鏈接庫哪個(gè)工程生成的并導(dǎo)出三個(gè)接口函數(shù)
很明顯由updatecore工程生成的sdologinentry.dll和sdologinentry64.dll的動態(tài)鏈接庫。
int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
{
TCHAR path[32768*2] = {0};
DWORD len = GetEnvironmentVariable(_T("PATH"), path, _countof(path));
TCHAR buffer[MAX_PATH] = {0};
GetModuleFileName(g_hModule, buffer, _countof(buffer));
_stprintf(path+len, _T(";%s\\..\\sdologin\\"), buffer);
SetEnvironmentVariable(_T("PATH"), path);
SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;
// Skip update process or not
wchar_t buffer2[MAX_PATH] = {0};
wchar_t path2[MAX_PATH*2] = {0};
GetModuleFileNameW(g_hModule, buffer2, _countof(buffer2));
swprintf_s(path2, _countof(path2), L"%s\\..\\sdologin\\", buffer2);
LicenseManager::Initial(path2);
bool bExpired = LicenseManager::GetInstance()->GetValue<bool>("Expiration");
bool bSkipUpdate = LicenseManager::GetInstance()->GetValue<bool>("SkipUpdate");
if (!(bExpired == false && bSkipUpdate == true)) // !(未過期 && 跳過更新)
{
if (Update::GetInstance()->CheckLocalVersion())
{
if(!Update::GetInstance()->DownloadUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
{
return SDOA_FALSE;
}
}
else
{
if (!Update::GetInstance()->ForceUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
{
return SDOA_FALSE;
}
}
}
/*
#ifdef _WIN64
g_hSdoLogin = LoadLibrary(_T("sdologinsdk64.dll"));
#else
g_hSdoLogin = LoadLibrary(_T("sdologinsdk.dll"));
#endif
*/
GetModuleFileName(g_hModule, buffer, _countof(buffer));
#ifdef _WIN64
sprintf(buffer + strlen(buffer) - strlen("sdologinentry64.dll"), "sdologin\\sdologinsdk64.dll");
#else
sprintf(buffer + strlen(buffer) - strlen("sdologinentry.dll"), "sdologin\\sdologinsdk.dll");
#endif
g_hSdoLogin = LoadLibraryEx(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
LPSDOLInitialize pFun = (LPSDOLInitialize)GetProcAddress(g_hSdoLogin, "SDOLInitialize");
if(pFun)
{
return pFun(pAppInfo);
}
return SDOA_FALSE;
}
int WINAPI SDOLGetModule(REFIID riid, void** intf)
{
LPSDOLGetModule pFun = (LPSDOLGetModule)GetProcAddress(g_hSdoLogin, "SDOLGetModule");
if(pFun)
{
return pFun(riid, intf);
}
return false;
}
int WINAPI SDOLTerminal()
{
LPSDOLTerminal pFun = (LPSDOLTerminal)GetProcAddress(g_hSdoLogin, "SDOLTerminal");
int ret = SDOA_FALSE;
if(pFun)
{
ret = pFun();
}
FreeLibrary(g_hSdoLogin);
if(ret == SDOL_ERRORCODE_OK)
{
Update::GetInstance()->SetupUpdate();
}
Update::Destroy();
return ret;
}
int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
{
? TCHAR path[32768*2] = {0};
? DWORD len = GetEnvironmentVariable(_T(“PATH”), path, _countof(path));? TCHAR buffer[MAX_PATH] = {0};
? GetModuleFileName(g_hModule, buffer, _countof(buffer));? _stprintf(path+len, _T(“;%s\…\sdologin\”), buffer);
? SetEnvironmentVariable(_T(“PATH”), path);
? SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;
? SetEnvironmentVariable(_T(“PATH”), path);
? SDOLAppInfo* pInfo = (SDOLAppInfo*)pAppInfo;
? // Skip update process or not
? wchar_t buffer2[MAX_PATH] = {0};
? wchar_t path2[MAX_PATH*2] = {0};
? GetModuleFileNameW(g_hModule, buffer2, _countof(buffer2));
? swprintf_s(path2, _countof(path2), L"%s\…\sdologin\", buffer2);? LicenseManager::Initial(path2);
? bool bExpired = LicenseManager::GetInstance()->GetValue(“Expiration”);
? bool bSkipUpdate = LicenseManager::GetInstance()->GetValue(“SkipUpdate”);? if (!(bExpired == false && bSkipUpdate == true)) // !(未過期 && 跳過更新)
? {
? if (Update::GetInstance()->CheckLocalVersion())
? {
? if(!Update::GetInstance()->DownloadUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
? {
? return SDOA_FALSE;
? }
? }
? else
? {
? if (!Update::GetInstance()->ForceUpdate(pInfo->AppID, pInfo->AreaId, pInfo->GroupId))
? {
? return SDOA_FALSE;
? }
? }
? }/*
#ifdef _WIN64
g_hSdoLogin = LoadLibrary(_T(“sdologinsdk64.dll”));
#else
g_hSdoLogin = LoadLibrary(_T(“sdologinsdk.dll”));
#endif
*/? GetModuleFileName(g_hModule, buffer, _countof(buffer));
#ifdef _WIN64
sprintf(buffer + strlen(buffer) - strlen(“sdologinentry64.dll”), “sdologin\sdologinsdk64.dll”);
#else
sprintf(buffer + strlen(buffer) - strlen(“sdologinentry.dll”), “sdologin\sdologinsdk.dll”);
#endif? g_hSdoLogin = LoadLibraryEx(buffer, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
? LPSDOLInitialize pFun = (LPSDOLInitialize)GetProcAddress(g_hSdoLogin, “SDOLInitialize”);
? if(pFun)
? {
? return pFun(pAppInfo);
? }
? return SDOA_FALSE;}
代碼解釋:
- 這段代碼是一個(gè)函數(shù)
SDOLInitialize
的實(shí)現(xiàn),以下是它的主要功能:- 獲取當(dāng)前環(huán)境變量中的
PATH
,并向其中添加一個(gè)目錄路徑。這個(gè)目錄路徑是sdologin
目錄,它相對于當(dāng)前執(zhí)行程序的目錄。 - 初始化
LicenseManager
,它的目的是獲取和檢查許可證信息。 - 檢查許可證信息中的 “Expiration” 和 “SkipUpdate” 值,根據(jù)這些值決定是否跳過更新過程。
- 如果不跳過更新,檢查本地版本并嘗試下載或強(qiáng)制更新。
- 最后,通過構(gòu)建動態(tài)鏈接庫文件路徑,加載
sdologinsdk.dll
或sdologinsdk64.dll
(取決于系統(tǒng)架構(gòu)),同理并調(diào)用動態(tài)鏈接庫中的SDOLInitialize
函數(shù)。
- 獲取當(dāng)前環(huán)境變量中的
- 總體來說,這段代碼的功能是在初始化時(shí)檢查許可證信息,決定是否需要進(jìn)行更新,并加載相應(yīng)的動態(tài)鏈接庫以繼續(xù)應(yīng)用程序的初始化過程。根據(jù)許可證信息,它可能跳過更新或執(zhí)行更新操作。這種方式通常用于軟件的自動更新或版本管理。
int WINAPI SDOLGetModule(REFIID riid, void** intf)
{
LPSDOLGetModule pFun = (LPSDOLGetModule)GetProcAddress(g_hSdoLogin, “SDOLGetModule”);
if(pFun)
{
return pFun(riid, intf);
}
return false;
}
代碼解釋:
- 這段代碼是一個(gè)函數(shù)
SDOLGetModule
的實(shí)現(xiàn),以下是它的主要功能:- 首先,它通過
GetProcAddress
函數(shù)嘗試從同理并調(diào)用動態(tài)鏈接庫中的加載的g_hSdoLogin
動態(tài)鏈接庫中獲取名為 “SDOLGetModule” 的函數(shù)的地址,這個(gè)函數(shù)似乎是一個(gè)用于獲取模塊的接口(COM 接口)的函數(shù)。 - 如果成功獲取到該函數(shù)的地址,它調(diào)用該函數(shù),并將
riid
和intf
參數(shù)傳遞給它。 - 如果獲取和調(diào)用都成功,函數(shù)返回從
pFun
調(diào)用的結(jié)果。 - 如果無法獲取到該函數(shù)的地址,或者獲取和調(diào)用失敗,函數(shù)返回
false
。
- 首先,它通過
- 這段代碼似乎是為了實(shí)現(xiàn)動態(tài)加載的模塊系統(tǒng),其中
SDOLGetModule
函數(shù)用于獲取指定接口的模塊。如果成功獲取到并調(diào)用了模塊中的SDOLGetModule
函數(shù),它將返回相應(yīng)的結(jié)果,否則返回false
表示失敗。通常,這種方式用于插件系統(tǒng)或模塊化的應(yīng)用程序,可以在運(yùn)行時(shí)加載不同的模塊并獲取它們的接口。
int WINAPI SDOLTerminal()
{
LPSDOLTerminal pFun = (LPSDOLTerminal)GetProcAddress(g_hSdoLogin, “SDOLTerminal”);
int ret = SDOA_FALSE;
if(pFun)
{
ret = pFun();
}? FreeLibrary(g_hSdoLogin);
? if(ret == SDOL_ERRORCODE_OK)
? {
? Update::GetInstance()->SetupUpdate();
? }
? Update::Destroy();? return ret;
}
代碼解釋:
-
這段代碼是一個(gè)函數(shù)
SDOLTerminal
的實(shí)現(xiàn),以下是它的主要功能:- 首先,它通過
GetProcAddress
函數(shù)嘗試從同理并調(diào)用動態(tài)鏈接庫中的加載的g_hSdoLogin
動態(tài)鏈接庫中獲取名為 “SDOLTerminal” 的函數(shù)的地址,似乎是一個(gè)用于終止模塊操作的函數(shù)。 - 如果成功獲取到該函數(shù)的地址,它調(diào)用該函數(shù),并將返回的結(jié)果存儲在
ret
變量中。 - 接著,它使用
FreeLibrary
函數(shù)釋放g_hSdoLogin
動態(tài)鏈接庫,即卸載模塊。 - 如果
ret
的值等于SDOL_ERRORCODE_OK
,則表示成功執(zhí)行模塊操作,它會調(diào)用Update::GetInstance()->SetupUpdate()
來設(shè)置更新,否則跳過這一步。 - 最后,它調(diào)用
Update::Destroy()
來釋放更新相關(guān)的資源,并返回ret
的值。
- 首先,它通過
-
這段代碼的主要作用是在模塊操作結(jié)束時(shí),執(zhí)行一些清理工作,包括釋放動態(tài)鏈接庫,進(jìn)行更新設(shè)置,以及資源的銷毀。這通常用于模塊的初始化和終止過程。
解釋如何調(diào)用到sdologinentry.dll或者sdologinentry64.dll庫中的三個(gè)函數(shù):
SDOLInitialize
SDOLGetModule
SDOLTerminal
LIBRARY "updatecore"
EXPORTS
igwInitialize
igwGetModule
igwTerminal
SDOLInitialize
SDOLGetModule
SDOLTerminal
資源解釋:
- 這是一個(gè)動態(tài)鏈接庫(DLL)的導(dǎo)出符號定義部分。在這個(gè)定義中:
-
LIBRARY "updatecore"
表示該動態(tài)鏈接庫的名稱為 “updatecore”。 -
EXPORTS
下面列出了一系列函數(shù)名稱,它們將會在該 DLL 中被導(dǎo)出,以便其他模塊或程序可以調(diào)用這些函數(shù)。這些函數(shù)包括了igwInitialize
、igwGetModule
、igwTerminal
、SDOLInitialize
、SDOLGetModule
以及SDOLTerminal
。
-
- 這些導(dǎo)出函數(shù)通常是其他程序或模塊需要使用的接口。通過將它們導(dǎo)出,其他程序可以通過動態(tài)鏈接的方式加載這個(gè) DLL,并使用這些函數(shù)來執(zhí)行特定的操作。在你之前提供的代碼中,通過
GetProcAddress
函數(shù)來獲取并調(diào)用這些函數(shù),這使得你可以在運(yùn)行時(shí)動態(tài)加載和使用這些功能。
10.4、sdologinsdk.dll或者sdologinsdk64.dll動態(tài)鏈接庫哪個(gè)工程生成并導(dǎo)出三個(gè)接口函數(shù)
SDOLInitialize
SDOLGetModule
SDOLTerminal
很明顯由sdk工程生成的sdologinsdk.dll和sdologinsdk64.dll的動態(tài)鏈接庫。
static SDOLLogin* g_pSDOLLogin = NULL;
static SDOLInfo* g_pSDOLInfo = NULL;
bool _SDOLGetModule(REFIID riid, void** intf);
bool _igwGetModule(REFIID riid, void** intf);
int WINAPI SDOLInitializeInternal(const SDOLAppInfo* pAppInfo)
{
TRACET();
TRACEI(_T("pAppInfo[0x%x]\n"), pAppInfo);
if(pAppInfo == NULL || pAppInfo->Size != sizeof(SDOLAppInfo))
{
TRACEW("SDOLII pAppInfo error.");
return SDOL_ERRORCODE_INVALIDPARAM;
}
if(!ModuleLoginSDK::Initial(pAppInfo))
{
TRACEW("ModuleLoginSDK::Initial() failed.");
return SDOL_ERRORCODE_FAILED;
}
TRACEI(_T("AppID[%d] AppName[%s] AppVer[%s] AreaId[%d] GroupId[%d]\n"),
pAppInfo->AppID, pAppInfo->AppName, pAppInfo->AppVer, pAppInfo->AreaId, pAppInfo->GroupId);
//ModuleLoginSDK::GetInstance()->SetAppInfo(pAppInfo);
g_pSDOLLogin = new SDOLLogin();
g_pSDOLInfo = new SDOLInfo();
return SDOL_ERRORCODE_OK;
};
bool _InitObjects( const SDOLAppInfo& appInfo ) ;
int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
{
TRACET();
TRACEI(_T("pAppInfo[0x%x]\n"), pAppInfo);
if (NULL != pAppInfo)
{
TRACEI(_T("pAppInfo->Size[%d]\n"), pAppInfo->Size);
TRACEI(_T("pAppInfo->AppID[%d]\n"), pAppInfo->AppID);
TRACEI(_T("pAppInfo->AppName[%s]\n"), pAppInfo->AppName);
TRACEI(_T("pAppInfo->AppVer[%s]\n"), pAppInfo->AppVer);
TRACEI(_T("pAppInfo->AreaId[%d]\n"), pAppInfo->AreaId);
}
// zlc bool res = _InitObjects(*pAppInfo);
SDOLAppInfo struAppInfo;
memcpy(&struAppInfo, pAppInfo, sizeof(SDOLAppInfo));
if (struAppInfo.AppID == 0)
struAppInfo.AppID = 791000388; //zlc here
bool res = _InitObjects(struAppInfo);
if (!res)
{
return SDOL_ERRORCODE_FAILED;
}
ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame);
return SDOL_ERRORCODE_OK;
};
int WINAPI SDOLGetModule(REFIID riid, void** intf)
{
TRACET();
OLECHAR* guid = NULL;
StringFromIID(riid, &guid);
TRACEI(_T("0 SDOLGetModule riid[%s]"), guid);
bool res = false;
res = _SDOLGetModule(riid, intf);
if (!res)
{
res = _igwGetModule(riid, intf);
}
if (res)
{
OLECHAR* guid = NULL;
StringFromIID(riid, &guid);
TRACEI(_T("1 SDOLGetModule riid[%s]"), guid);
}
return res ? SDOL_ERRORCODE_OK:SDOL_ERRORCODE_FAILED;
};
int WINAPI SDOLTerminal()
{
TRACET();
TRACEI(_T(""));
int ret = ModuleLoginSDK::Destroy();
SAFE_DELETE(g_pSDOLLogin);
return ret == ShutdownSuccess ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
};
bool _SDOLGetModule(REFIID riid, void** intf)
{
TRACET();
TRACEI(_T(""));
if(riid == __uuidof(ISDOLLogin))
{
*intf = (void*)(ISDOLLogin*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin2))
{
*intf = (void*)(ISDOLLogin2*)g_pSDOLLogin;
return true;
}
if (riid == __uuidof(ISDOLInfo))
{
*intf = (void*)(ISDOLInfo*)g_pSDOLInfo;
return true;
}
if(riid == __uuidof(ISDOLLogin3))
{
*intf = (void*)(ISDOLLogin3*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin4))
{
*intf = (void*)(ISDOLLogin4*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin5))
{
*intf = (void*)(ISDOLLogin5*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin6))
{
*intf = (void*)(ISDOLLogin6*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin7))
{
*intf = (void*)(ISDOLLogin7*)g_pSDOLLogin;
return true;
}
if(riid == __uuidof(ISDOLLogin8))
{
*intf = (void*)(ISDOLLogin8*)g_pSDOLLogin;
return true;
}
return false;
};
static SDOLLogin* g_pSDOLLogin = NULL;
static SDOLInfo* g_pSDOLInfo = NULL;
bool _SDOLGetModule(REFIID riid, void** intf);
bool _igwGetModule(REFIID riid, void** intf);int WINAPI SDOLInitializeInternal(const SDOLAppInfo* pAppInfo)
{
TRACET();
TRACEI(_T(“pAppInfo[0x%x]\n”), pAppInfo);? if(pAppInfo == NULL || pAppInfo->Size != sizeof(SDOLAppInfo))
? {
? TRACEW(“SDOLII pAppInfo error.”);
? return SDOL_ERRORCODE_INVALIDPARAM;
? }? if(!ModuleLoginSDK::Initial(pAppInfo))
? {
? TRACEW(“ModuleLoginSDK::Initial() failed.”);
? return SDOL_ERRORCODE_FAILED;
? }? TRACEI(_T(“AppID[%d] AppName[%s] AppVer[%s] AreaId[%d] GroupId[%d]\n”),
? pAppInfo->AppID, pAppInfo->AppName, pAppInfo->AppVer, pAppInfo->AreaId, pAppInfo->GroupId);? //ModuleLoginSDK::GetInstance()->SetAppInfo(pAppInfo);
? g_pSDOLLogin = new SDOLLogin();
? g_pSDOLInfo = new SDOLInfo();? return SDOL_ERRORCODE_OK;
};
代碼解釋:
-
這段代碼定義了一個(gè)名為
SDOLInitializeInternal
的函數(shù),以下是它的主要功能:- 在函數(shù)開始時(shí),通過
TRACEI
函數(shù)和TRACEW
函數(shù)輸出一些信息,用于調(diào)試和日志記錄。 - 首先,它檢查傳入的
pAppInfo
參數(shù)是否為NULL
或其大小是否與sizeof(SDOLAppInfo)
相符。如果不符合條件,函數(shù)會返回SDOL_ERRORCODE_INVALIDPARAM
表示參數(shù)無效。 - 接著,如果上述檢查通過,它調(diào)用
ModuleLoginSDK::Initial(pAppInfo)
函數(shù),嘗試進(jìn)行一些初始化操作。如果初始化失敗,函數(shù)返回SDOL_ERRORCODE_FAILED
表示初始化失敗。 - 如果初始化成功,它繼續(xù)輸出
pAppInfo
中的一些信息,包括了AppID
、AppName
、AppVer
、AreaId
和GroupId
。 - 然后,它創(chuàng)建了兩個(gè)對象:
g_pSDOLLogin
和g_pSDOLInfo
,分別是SDOLLogin
和SDOLInfo
的實(shí)例。 - 最后,函數(shù)返回
SDOL_ERRORCODE_OK
表示初始化成功。
- 在函數(shù)開始時(shí),通過
-
這段代碼的主要目的是在應(yīng)用程序的初始化過程中,根據(jù)傳入的應(yīng)用信息進(jìn)行一些初始化工作,包括了調(diào)用
ModuleLoginSDK::Initial
函數(shù),創(chuàng)建SDOLLogin
和SDOLInfo
的對象。如果初始化成功,函數(shù)返回成功狀態(tài)碼,否則返回失敗狀態(tài)碼。
bool _InitObjects( const SDOLAppInfo& appInfo ) ;
int WINAPI SDOLInitialize(const SDOLAppInfo* pAppInfo)
{
TRACET();
TRACEI(_T(“pAppInfo[0x%x]\n”), pAppInfo);
if (NULL != pAppInfo)
{
TRACEI(_T(“pAppInfo->Size[%d]\n”), pAppInfo->Size);
TRACEI(_T(“pAppInfo->AppID[%d]\n”), pAppInfo->AppID);
TRACEI(_T(“pAppInfo->AppName[%s]\n”), pAppInfo->AppName);
TRACEI(_T(“pAppInfo->AppVer[%s]\n”), pAppInfo->AppVer);
TRACEI(_T(“pAppInfo->AreaId[%d]\n”), pAppInfo->AreaId);
}? // zlc bool res = _InitObjects(*pAppInfo);
? SDOLAppInfo struAppInfo;
? memcpy(&struAppInfo, pAppInfo, sizeof(SDOLAppInfo));
? if (struAppInfo.AppID == 0)
? struAppInfo.AppID = 791000388; //zlc here
? bool res = _InitObjects(struAppInfo);
? if (!res)
? {
? return SDOL_ERRORCODE_FAILED;
? }? ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame);
? return SDOL_ERRORCODE_OK;
};
代碼解釋:
-
這段代碼是一個(gè)名為
SDOLInitialize
的函數(shù)的實(shí)現(xiàn),以下是它的主要功能:- 在函數(shù)開始時(shí),通過一系列
TRACEI
函數(shù)調(diào)用來輸出一些信息,這些信息包括了pAppInfo
參數(shù)的各個(gè)成員的值,以便進(jìn)行調(diào)試和日志記錄。 - 接著,它創(chuàng)建一個(gè)名為
struAppInfo
的局部變量,并通過memcpy
函數(shù)將pAppInfo
的內(nèi)容復(fù)制到struAppInfo
中。然后,它檢查struAppInfo
中的AppID
是否為 0,如果是,將其設(shè)置為 791000388。 - 接下來,它調(diào)用
_InitObjects
函數(shù),將struAppInfo
作為參數(shù)傳遞給它。_InitObjects
函數(shù)可能用于初始化一些對象或資源,這部分的具體邏輯在_InitObjects
函數(shù)中實(shí)現(xiàn)。 - 如果
_InitObjects
返回true
表示初始化成功,它將調(diào)用ModuleLoginSDK::GetInstance()->SetWindowMode(SetWindowModeReq::OutsideGame)
來設(shè)置某種窗口模式。窗口模式的設(shè)置可能與應(yīng)用程序的顯示方式有關(guān)。 - 最后,如果初始化成功,函數(shù)返回
SDOL_ERRORCODE_OK
,否則返回SDOL_ERRORCODE_FAILED
表示初始化失敗。
- 在函數(shù)開始時(shí),通過一系列
-
總的來說,這段代碼的目的是在應(yīng)用程序初始化過程中,根據(jù)傳入的應(yīng)用信息進(jìn)行一些初始化工作,包括了調(diào)用
_InitObjects
函數(shù)和設(shè)置窗口模式。如果初始化成功,返回成功狀態(tài)碼,否則返回失敗狀態(tài)碼。
int WINAPI SDOLGetModule(REFIID riid, void** intf)
{
TRACET();? OLECHAR* guid = NULL;
? StringFromIID(riid, &guid);
? TRACEI(_T(“0 SDOLGetModule riid[%s]”), guid);? bool res = false;
? res = _SDOLGetModule(riid, intf);
? if (!res)
? {
? res = _igwGetModule(riid, intf);
? }? if (res)
? {
? OLECHAR* guid = NULL;
? StringFromIID(riid, &guid);
? TRACEI(_T(“1 SDOLGetModule riid[%s]”), guid);
? }? return res ? SDOL_ERRORCODE_OK:SDOL_ERRORCODE_FAILED;
};
代碼解釋:
- 這段代碼是一個(gè)名為
SDOLGetModule
的函數(shù)的實(shí)現(xiàn),以下是它的主要功能:- 在函數(shù)開始時(shí),通過
TRACEI
函數(shù)和StringFromIID
函數(shù)輸出一些信息,包括riid
參數(shù)的 GUID。 - 接著,它創(chuàng)建一個(gè)名為
guid
的指針,并通過StringFromIID
函數(shù)將riid
轉(zhuǎn)換為字符串形式,并將結(jié)果存儲在guid
中。 - 然后,它調(diào)用
_SDOLGetModule
函數(shù),傳遞riid
和intf
作為參數(shù),以嘗試獲取模塊。 - 如果
_SDOLGetModule
返回false
(表示獲取模塊失?。又{(diào)用_igwGetModule
函數(shù),再次嘗試獲取模塊。 - 如果成功獲取到模塊,它再次輸出
riid
的信息,然后返回SDOL_ERRORCODE_OK
表示成功。 - 如果兩次嘗試都沒有成功獲取模塊,它最終返回
SDOL_ERRORCODE_FAILED
表示失敗。
- 在函數(shù)開始時(shí),通過
- 總的來說,這段代碼的目的是嘗試獲取一個(gè)模塊,首先通過
_SDOLGetModule
嘗試,如果失敗再通過_igwGetModule
嘗試。如果成功獲取到模塊,它返回成功狀態(tài)碼,否則返回失敗狀態(tài)碼。
int WINAPI SDOLTerminal()
{
TRACET();
TRACEI(_T(“”));? int ret = ModuleLoginSDK::Destroy();
? SAFE_DELETE(g_pSDOLLogin);
? return ret == ShutdownSuccess ? SDOL_ERRORCODE_OK : SDOL_ERRORCODE_FAILED;
}
代碼解釋:
- 這段代碼是一個(gè)名為
SDOLTerminal
的函數(shù)的實(shí)現(xiàn),以下是它的主要功能:- 在函數(shù)開始時(shí),通過
TRACEI
函數(shù)輸出一些信息,用于調(diào)試和日志記錄。 - 接著,它調(diào)用
ModuleLoginSDK::Destroy()
函數(shù),該函數(shù)可能用于銷毀一些模塊相關(guān)的資源和對象。 - 將
ModuleLoginSDK::Destroy()
返回的結(jié)果存儲在ret
變量中,這個(gè)結(jié)果可能是一個(gè)表示銷毀操作是否成功的值。 - 然后,它通過
SAFE_DELETE(g_pSDOLLogin)
來釋放g_pSDOLLogin
所指向的對象或資源。這個(gè)宏可能用于安全地刪除指針,并將指針置為nullptr
。 - 最后,如果
ret
的值等于ShutdownSuccess
,它返回SDOL_ERRORCODE_OK
表示終止成功,否則返回SDOL_ERRORCODE_FAILED
表示終止失敗。
- 在函數(shù)開始時(shí),通過
- 這段代碼的主要目的是在應(yīng)用程序終止時(shí)執(zhí)行一些清理操作,包括銷毀模塊相關(guān)的資源和對象,然后返回適當(dāng)?shù)臓顟B(tài)碼以表示終止的結(jié)果。
bool _SDOLGetModule(REFIID riid, void** intf)
{
TRACET();
TRACEI(_T(“”));? if(riid == __uuidof(ISDOLLogin))
? {
? intf = (void)(ISDOLLogin*)g_pSDOLLogin;
? return true;
? }
? if(riid == __uuidof(ISDOLLogin2))
? {
? intf = (void)(ISDOLLogin2*)g_pSDOLLogin;
? return true;
? }
? if (riid == __uuidof(ISDOLInfo))
? {
? intf = (void)(ISDOLInfo*)g_pSDOLInfo;
? return true;
? }
? if(riid == __uuidof(ISDOLLogin3))
? {
? intf = (void)(ISDOLLogin3*)g_pSDOLLogin;
? return true;
? }
? if(riid == __uuidof(ISDOLLogin4))
? {
? intf = (void)(ISDOLLogin4*)g_pSDOLLogin;
? return true;
? }
? if(riid == __uuidof(ISDOLLogin5))
? {
? intf = (void)(ISDOLLogin5*)g_pSDOLLogin;
? return true;
? }
? if(riid == __uuidof(ISDOLLogin6))
? {
? intf = (void)(ISDOLLogin6*)g_pSDOLLogin;
? return true;
? }
? if(riid == __uuidof(ISDOLLogin7))
? {
? intf = (void)(ISDOLLogin7*)g_pSDOLLogin;
? return true;
? }
? if(riid == __uuidof(ISDOLLogin8))
? {
? intf = (void)(ISDOLLogin8*)g_pSDOLLogin;
? return true;
? }? return false;
};
代碼解釋:
- 這段代碼是一個(gè)名為
_SDOLGetModule
的函數(shù)的實(shí)現(xiàn),以下是它的主要功能:- 在函數(shù)開始時(shí),通過
TRACEI
函數(shù)輸出一些信息,用于調(diào)試和日志記錄。 - 然后,它檢查傳入的
riid
參數(shù)是否等于特定的接口類型的 UUID(GUID)。如果riid
匹配某個(gè)特定接口類型的 UUID,它將將*intf
指向相應(yīng)的接口指針,并返回true
表示成功。 - 如果
riid
不匹配任何已知的接口類型,它返回false
表示失敗。
- 在函數(shù)開始時(shí),通過
- 這段代碼的主要目的是根據(jù)傳入的
riid
參數(shù),嘗試獲取對應(yīng)的接口,并將接口指針存儲在*intf
中,以便其他部分的代碼可以使用這些接口進(jìn)行操作。如果riid
匹配已知接口類型,則返回true
,否則返回false
。這通常用于實(shí)現(xiàn) COM 接口的獲取和對象的實(shí)例化。
bool _igwGetModule(REFIID riid, void** intf)
{
if(riid == __uuidof(ISDOAApp))
{
intf = (void)(ISDOAApp*)g_pSDOAApp4;
return true;
}
if(riid == __uuidof(ISDOAApp2))
{
intf = (void)(ISDOAApp2*)g_pSDOAApp4;
return true;
}
if(riid == __uuidof(ISDOAApp3))
{
intf = (void)(ISDOAApp3*)g_pSDOAApp4;
return true;
}
if(riid == __uuidof(ISDOAApp4))
{
intf = (void)(ISDOAApp4*)g_pSDOAApp4;
return true;
}
if(riid == __uuidof(IGW2::ISDOAAppEx))
{
intf = (void)(IGW2::ISDOAAppEx*)g_pSDOAAppEx;
return true;
}
if(riid == __uuidof(ISDOAAppUtils))
{
intf = (void)(ISDOAAppUtils*)g_pSDOAAppUtils;
return true;
}
if(riid == __uuidof(ISDOAClientService))
{
intf = (void)(ISDOAClientService*)g_pSDOAClientService;
return true;
}? if(riid == __uuidof(IGPLUSApp))
? {
? intf = (void)(IGPLUSApp*)CGPlusManager::GetInstance()->getGplusAppObject();
? return true;
? }? //if(Dx7GetModule(riid, intf))
? //{
? // return true;
? //}
? if(Dx8GetModule(riid, intf))
? {
? return true;
? }
? if(Dx9GetModule(riid, intf))
? {
? return true;
? }
? if(Dx11GetModule(riid, intf))
? {
? return true;
? }
? if(GDIGetModule(riid, intf))
? {
? return true;
? }
? if(DDrawGetModule(riid, intf))
? {
? return true;
? }
? return false;}
代碼解釋:
-
這段代碼是一個(gè)名為
_igwGetModule
的函數(shù)的實(shí)現(xiàn),以下是它的主要功能:- 它檢查傳入的
riid
參數(shù)是否等于特定的接口類型的 UUID(GUID)。如果riid
匹配某個(gè)特定接口類型的 UUID,它將將*intf
指向相應(yīng)的接口指針,并返回true
表示成功。 - 如果
riid
不匹配已知的接口類型,它繼續(xù)檢查其他接口類型,包括Dx8GetModule
、Dx9GetModule
、Dx11GetModule
、GDIGetModule
、DDrawGetModule
等。如果傳入的riid
匹配這些接口類型中的任何一個(gè),它同樣將*intf
指向相應(yīng)的接口指針,并返回true
表示成功。 - 如果所有的檢查都失敗,它最終返回
false
表示沒有匹配的接口。
- 它檢查傳入的
-
這段代碼的主要目的是根據(jù)傳入的
riid
參數(shù),嘗試獲取對應(yīng)的接口,并將接口指針存儲在*intf
中,以便其他部分的代碼可以使用這些接口進(jìn)行操作。這是一種通用的接口獲取機(jī)制,用于獲取不同接口類型的對象。如果riid
匹配已知的接口類型,它返回true
,否則返回false
。這通常用于實(shí)現(xiàn) COM 接口的獲取和對象的實(shí)例化。
解釋如何調(diào)用到sdologinsdk.dll或者sdologinsdk64.dll庫中的三個(gè)函數(shù):
LIBRARY “sdologinsdk”
EXPORTS
SDOLInitialize
SDOLGetModule
SDOLTerminal
igwInitialize
igwGetModule
igwTerminal文章來源:http://www.zghlxwxcb.cn/news/detail-653963.html
代碼解釋:
- 這段代碼定義了一個(gè)名為 “sdologinsdk” 的動態(tài)鏈接庫(DLL)的導(dǎo)出符號,它列出了一系列函數(shù)名稱,這些函數(shù)將會在該 DLL 中被導(dǎo)出,以便其他模塊或程序可以通過動態(tài)鏈接的方式調(diào)用這些函數(shù)。導(dǎo)出的函數(shù)包括了:
SDOLInitialize
SDOLGetModule
SDOLTerminal
igwInitialize
igwGetModule
igwTerminal
- 這些導(dǎo)出函數(shù)通常是其他程序或模塊需要使用的接口。通過將它們導(dǎo)出,其他程序可以在運(yùn)行時(shí)動態(tài)加載這個(gè) DLL,并使用這些函數(shù)來執(zhí)行特定的操作。這種方式通常用于插件系統(tǒng)或模塊化的應(yīng)用程序,允許不同的模塊或插件在運(yùn)行時(shí)添加到應(yīng)用程序中,以擴(kuò)展其功能。
到了這里,關(guān)于typedef函數(shù)代碼段解釋以及部分Windows下的系統(tǒng)函數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!