Lua 代理 DLL 四 |
|
缺点是
目前,依赖关系有些混合。我希望改进这一点。目前,它需要
请注意,此解决方案不适用于使用 x64 的 MSVC,因为 'naked' 属性和 __asm 命令不受 x64 编译器的支持。
makeproxy.lua:
local CFILE = "luaproxy.c" -- Name of the C file for the proxy DLL local SYMBOLS = "luasymbols.h" -- Name of the file of Lua symbols local LUADLL = "lua51.dll" -- Name of a real Lua DLL (to get exported symbols) ---------------------------------------------------------------------- local cfile = assert(io.open(CFILE, "w")) cfile:write [=[ #include <windows.h> static struct { #define SYMBOL(name) FARPROC name; #include "luasymbols.h" #undef SYMBOL } s_funcs; /* Macro for defining a proxy function. This is a direct jump (single "jmp" assembly instruction"), preserving stack and return address. The following uses MSVC inline assembly which may not be portable with other compilers. */ #define SYMBOL(name) \ void __declspec(dllexport,naked) name() { __asm { jmp s_funcs.name } } #include "luasymbols.h" #undef SYMBOL BOOL APIENTRY DllMain(HANDLE module, DWORD reason, LPVOID reserved) { HANDLE h = GetModuleHandle(NULL); #define SYMBOL(name) s_funcs.name = GetProcAddress(h, #name); #include "luasymbols.h" #undef SYMBOL return TRUE; } ]=] cfile:close() symbols = io.popen("pexports "..LUADLL) symfile = io.open(SYMBOLS, "w") for sym in symbols:lines() do -- Skip the LIBRARY and EXPORTS lines start = sym:sub(1,3) if start ~= "LIB" and start ~= "EXP" then symfile:write("SYMBOL("..sym..")\n") end end symbols:close() symfile:close() os.execute(table.concat({ "cl /O2 /LD /GS-", CFILE, "/link /out:lua51.dll /nodefaultlib /entry:DllMain kernel32.lib"}, " "))
要使用代理,只需将构建的 `lua51.dll` 放在您的 `PATH` 上,而不是标准的 `lua51.dll`。静态链接到 `lua51.dll` 的扩展将拾取它并自动使用主程序中包含的静态 Lua 运行时。当然,所有正常的 C 运行时问题仍然适用 - 主程序和任何动态加载的扩展应该使用相同的 CRT,否则可能会出现问题(遗憾的是,C 没有像 Lua 那样提供很好的代理解决方案 :-))
-- PaulMoore?