我有一個帶有可執行檔案和 DLL 的 VS 解決方案。
在可執行檔案(主要)中:
__declspec(dllexport) void testExe()
{
printf("Hello from EXE");
}
__declspec(dllimport) void DoStuff();
int main()
{
DoStuff();
}
在 .dll (DLL) 中
__declspec(dllimport) void testExe();
__declspec(dllexport) void testDll()
{
printf("Hello from Dll");
}
__declspec(dllexport) void DoStuff()
{
testExe();
testDll();
}
我在 MAIN.exe 中鏈接了 Dll.lib,但仍然出現鏈接錯誤:
error LNK2019: unresolved external symbol "__declspec(dllimport) void __cdecl testExe(void)" referenced in function "void __cdecl DoStuff(void)"
我怎樣才能做到這一點?
uj5u.com熱心網友回復:
不要從 EXE 中匯出函式。從接受函式指標作為輸入的 DLL 中匯出一個函式,然后讓 EXE 在運行時呼叫該函式。
EXE檔案:
__declspec(dllimport) void SetFunc(void (*)());
__declspec(dllimport) void DoStuff();
void testExe()
{
printf("Hello from EXE");
}
int main()
{
SetFunc(testExe);
DoStuff();
}
元件:
typedef void (*lpFuncType)();
lpFuncType pExeFunc = NULL;
void testDll()
{
printf("Hello from Dll");
}
__declspec(dllexport) void SetFunc(lpFuncType func)
{
pExeFunc = func;
}
__declspec(dllexport) void DoStuff()
{
if (pExeFunc) pExeFunc();
testDll();
}
uj5u.com熱心網友回復:
回圈依賴在這里是一個問題。你必須打破這個回圈,否則你將有復雜而脆弱的構建程序來創建這個回圈。
打破這個回圈的一種方法是 Remy Lebeau 的回答。
另一種方法是引入另一個將包含的 dll testExe(),此 dll 將鏈接到可執行檔案和您的初始 dll,其中包含testDll(). 優點是您根本不必更改代碼,只需將可執行檔案拆分為可執行檔案和額外的 dll。
uj5u.com熱心網友回復:
用于GetModuleHandleW(NULL)獲取正在執行的 EXE 的模塊句柄。然后GetProcAddress用來獲取函式的地址。
注意 C 名稱修改和呼叫約定(使用 __stdcall 將添加類似 @4 的內容)更改函式名稱。為避免函式名稱更改,請extern "C"在匯出之前使用。
例子:
在 EXE 的 main.cpp 中:
//Want to use extern "C" so that the function name doesn't get mangled using C mangling rules
extern "C"
{
__declspec(dllexport) int DoStuff(int param1, int param2);
}
在從 EXE 匯入的 DLL 中:
//Declare a function pointer type named "DoStuff_FUNC", this makes it a lot easier to import functions
typedef (int DoStuff_FUNC)(int param1, int param2);
int DoStuff_WithinDll(int param1, int param2)
{
//Get the module handle from the executing EXE
HMODULE module = GetModuleHandleW(NULL);
//Type-cast "FARPROC" to our desired function type
DoStuff_FUNC DoStuff = (DoStuff_FUNC)GetProcAddress(module, "DoStuff");
if (DoStuff != NULL)
{
return DoStuff(param1, param2);
}
return -1;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/438370.html
