You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 03:35:44