頭檔案如下
#define CoverWinAPI extern "C" __declspec(dllexport)
CoverWinAPI BOOL RunDll();
CoverWinAPI void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName,PROC pfnCurrent,PROC pfnNew,HMODULE hmodCaller);
#pragma comment(linker,"/export:MyCreateWindowExW=_MyCreateWindowExW@48")
CoverWinAPI HWND WINAPI MyCreateWindowExW(
_In_opt_ DWORD dwExStyle,
_In_opt_ LPCWSTR lpClassName,
_In_opt_ LPCWSTR lpWindowName,
_In_ DWORD dwStyle,
_In_ int X,
_In_ int Y,
_In_ int nWidth,
_In_ int nHeight,
_In_opt_ HWND hWndParent,
_In_opt_ HMENU hMenu,
_In_opt_ HINSTANCE hInstance,
_In_opt_ LPVOID lpParam);
當我不使用#pragma 注釋時,匯出函式名稱為_MyCreateWindowExW@48。
但是當我使用時
#pragma comment(linker,"/export:MyCreateWindowExW=_MyCreateWindowExW@48")
,MSVC 編譯失敗并顯示unresolved external symbol _MyCreateWindowExW@48
。是什么導致了這個錯誤?
uj5u.com熱心網友回復:
您遇到的問題是由于編譯器修飾函式名稱的方式。
_MyCreateWindowExW@48
是一個 x86 風格的修飾名稱,僅適用于 x86 構建,它的 x64 對應物是簡單的MyCreateWindowExW
(x64 只有一個呼叫約定,類似于__cdecl
呼叫者是負責管理堆疊分配的那個)。
與官方檔案相反,export#pragma
和/EXPORT
linker 選項都不適用于未修飾的名稱,它們都希望名稱是完全修飾的。這里提到了這一點。
小筆記
從 Dll 匯出有幾種方法,例如:
__declspec(dllexport)
#pragma comment(linker,"/export:...")
或者link.exe /EXPORT
- 定義檔案
通常只使用其中一個就足夠了,因此在您的示例__declspec(dllexport)
中是多余的,考慮到它匯出一個裝飾名稱,這不是您想要的,更是如此。
解決方案 #1(IMO 很麻煩)
用于#ifdef
為每個平臺提供適當的修飾名稱:
#define CoverWinAPI extern "C"
CoverWinAPI BOOL RunDll();
CoverWinAPI void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller);
#ifndef _WIN64
#pragma comment(linker,"/export:MyCreateWindowExW=_MyCreateWindowExW@48")
#else
#pragma comment(linker,"/export:MyCreateWindowExW")
#endif
CoverWinAPI HWND WINAPI MyCreateWindowExW(...);
解決方案 #2(建議)
將 DEF 檔案添加到您的專案中:
LIBRARY CoverWinAPI
EXPORTS
MyCreateWindowExW
RunDll
ReplaceIATEntryInOneMod
然后你的宣告可以這樣重寫:
#define CoverWinAPI WINAPI
BOOL CoverWinAPI RunDll();
void CoverWinAPI ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller);
HWND CoverWinAPI MyCreateWindowExW(...);
這是有效的,因為顯然聯結器確實嘗試將 DEF 檔案條目與修飾和未修飾的名稱相匹配。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/489312.html
上一篇:為什么SymInitialize()呼叫CreateFile()?
下一篇:單擊滑鼠后使文本框文本消失