Lua模块从DllMain中推送C函数。

我有一个巨大的问题。你知道,Lua允许制作模块,你可以使用5.1(之前是loadlib)中的require()函数加载这些模块。

#define LUA extern "C" __declspec(dllexport) int __cdecl

static int l_TestFunc(lua_State * L)
{

    lua_pushboolean (L, 1); // return true

    return 1;
}

LUA luaopen_MyModule(lua_State *L)
{

    printf("test2");
    lua_pushcfunction(L, l_TestFunc);
    lua_setglobal(L, "TestFunc");

    return 1;
}

所以在Lua中,你只需要使用require("MyModule"),一切都能正常工作。(luaopen_*是入口点)

但我需要使用标准方法(DllMain作为入口点)。我尝试了,但它没有起作用。你有什么想法吗?

点赞
用户501459
用户501459

但我需要使用标准方式(DllMain 作为入口点)。我已经尝试过了但是它没有工作。你有什么想法吗?

如果定义了 DllMain,则 DllMain 总是您的入口点,但是您不能使用它来加载函数,因为您没有 Lua 状态将其加载那里。

当您在 Lua 代码中运行 "require" 时,执行该代码的应用程序(例如 lua.exe)将加载您的 DLL(调用 DllMain),然后调用 luaopen_MyModule 并传递执行 require 语句的 Lua 状态。 没有办法让您的 DllMain 访问该状态指针...

...

...嗯,没有普通的方法。 您可以想出一些方法,在加载 DLL 之前,主机应用程序将 Lua 状态的内存位置写入某些对您的 DLL 可访问的外部位置(注册表,文件等)。您的 DllMain 可以获取指针寄存器及其函数,并将指针寄存器写入该状态。不确定为什么您要这样做,但在 C 语言之类的语言中,技术上是可能的。

这将需要您编写主机,以便您可以安排写入状态。或者您可以有一个独立的模块,以普通方式加载,该模块写入 Lua_state 值,然后所有其他模块都可以从其 DllMain 访问它。

...

这很像一个 XY 问题。您愿意分享为什么要在 DllMain 中注册自己的功能?

2013-04-05 23:00:46
用户2226988
用户2226988

试试这个......

require("MyModule")luaopen_MyModule 中不要使用 MyModule 的名称,而是使用你的 DLL 加载到的可执行文件的名称。如果这样不起作用,将 require 调用更改为以 .exe 结尾的文件名。

Lua 的 require 会调用 Win32 LoadLibrary,然后调用 GetProcAddress 来查找 luaopen 函数。这两个调用都将使用 require() 的参数。而 PE-inject 似乎会使注入的 DLL 中的所有函数都看起来像在 EXE 模块中。所以,你需要让 LoadLibrary 返回 EXE 模块的句柄,然后 GetProcAddress 才能找到注入的 luaopen 函数。

这种方法可能不起作用的原因有几个。其中之一是 Lua 的 require 要求 DLL 文件名和 DLL 模块名匹配。这不是 Win32 的要求,因此对于你的便携式可执行文件可能并不适用。

2013-04-05 23:31:40