C++注入式DLL引入Lua依赖后构建失效问题求助
Lua C API注入式DLL失效问题排查与修复
问题描述
我正在开发一个基于Lua C API的注入式DLL,参考Lua嵌入C++的教程后尝试整合到注入式DLL中。未加入Lua相关代码时DLL运行正常,但调用Lua API后就失效。Visual Studio没有检测到编译错误,已经尝试把Lua库文件夹放到DLL同目录,问题依旧。使用Visual Studio 2019,代码如下:
//dllmain.cpp #include "pch.h" #include <string> #include <Windows.h> extern "C" { #include "lua542/include/lua.h" #include "lua542/include/lauxlib.h" #include "lua542/include/lualib.h" } #ifdef _WIN32 #pragma comment(lib, "lua542/liblua54.a") #endif bool was_pressed = false; bool IsKeyPressed() { bool is_pressed = (GetAsyncKeyState(0x4A) & 0x8000) != 0; if (!was_pressed && is_pressed) { was_pressed = is_pressed; return true; } was_pressed = is_pressed; return false; } DWORD WINAPI TestThread(HMODULE hModule) { lua_State* L = luaL_newstate(); while (true) { //Activates on pressing key "J" if (IsKeyPressed()) { std::string cmd = "a = 7 + 11"; luaL_openlibs(L); luaL_dostring(L, cmd.c_str()); } } return 0; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBoxA(NULL, "Test", "Test", MB_OK); CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)TestThread, hModule, 0, nullptr)); case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
问题排查与修复方案
- Lua库格式不兼容:你使用的
liblua54.a是MinGW编译的静态库,Visual Studio(MSVC)无法正确链接这类库。需替换为MSVC编译的Lua静态库lua54.lib,或改用动态链接库lua54.dll及配套导入库。若用动态库,需确保目标进程能加载到lua54.dll(可放入系统目录或进程所在目录)。 - 重复初始化Lua库:每次按键时调用
luaL_openlibs(L)会重复加载标准库,引发内存泄漏和状态异常。应将该调用移至线程循环前,仅执行一次。 - 线程无休眠导致高CPU占用:
while(true)循环无休眠会耗尽CPU资源,可能导致进程卡顿或被终止,需加入Sleep(10)降低占用。 - DllMain分支缺失break:
DLL_PROCESS_ATTACH分支未加break,会执行后续分支逻辑,虽当前影响不大,但不符合规范,需补充。
修复后的代码示例
//dllmain.cpp #include "pch.h" #include <string> #include <Windows.h> extern "C" { #include "lua542/include/lua.h" #include "lua542/include/lauxlib.h" #include "lua542/include/lualib.h" } #ifdef _WIN32 // 替换为MSVC版本的lua54.lib #pragma comment(lib, "lua542/lua54.lib") #endif bool was_pressed = false; bool IsKeyPressed() { bool is_pressed = (GetAsyncKeyState(0x4A) & 0x8000) != 0; if (!was_pressed && is_pressed) { was_pressed = is_pressed; return true; } was_pressed = is_pressed; return false; } DWORD WINAPI TestThread(HMODULE hModule) { lua_State* L = luaL_newstate(); if (!L) { // 初始化失败时退出线程 return 1; } luaL_openlibs(L); // 仅初始化一次标准库 while (true) { Sleep(10); // 降低CPU占用 if (IsKeyPressed()) { std::string cmd = "a = 7 + 11"; int result = luaL_dostring(L, cmd.c_str()); if (result != LUA_OK) { // 捕获Lua执行错误,便于调试 const char* err = lua_tostring(L, -1); MessageBoxA(NULL, err, "Lua Error", MB_OK); lua_pop(L, 1); } } } lua_close(L); // 规范收尾,虽循环不会退出 return 0; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: MessageBoxA(NULL, "Test", "Test", MB_OK); CloseHandle(CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)TestThread, hModule, 0, nullptr)); break; // 补充break case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
内容的提问来源于stack exchange,提问作者Anonymous Acid
相关产品推荐
相关产品推荐

