Lua 代理 DLL 二 |
|
该实用程序可以为任何类型的主机构建代理 DLL,它不受 Lua 相关主机的限制。
该实用程序假设(并需要)MinGW 开发系统。
该实用程序包含一个“公共”函数:CreateProxyDll
。该函数接受一个参数,一个表,该表必须指定以下字段
PROXY : (path)name of the proxy DLL to build HOST : (path)name of the host library file (file must exist) DEFFILE : (path)name of the definition file (file must exist)
示例 1:允许将与 lua5.1.dll 和 lua51.dll 中的任何一个链接的应用程序或库组合使用
CreateProxyDll { PROXY = "lua51.dll", HOST = "c:\\exe\\lua5.1.dll", DEFFILE = "liblua5.1.def", }
示例 2:使静态构建的 Lua 解释器能够安全地require()
外部库
CreateProxyDll { PROXY = "lua5.1.dll", HOST = "c:\\exe\\lua51x.exe", DEFFILE = "liblua5.1.def", }
mkproxy.lua
-- Name: mkproxy.lua -- Goal: Create a proxy DLL that redirects all calls to the "host" library -- Written by: Shmuel Zeigerman -- License: public domain local CFile = [[ #include <windows.h> BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD Reason, LPVOID Reserved) { return TRUE; } ]] local function execute(s) assert(0 == os.execute(s)) end local function CreateObjectFile (objname) assert(objname:match("%.o$")) local cname = objname:gsub("%.o$", ".c") local fp = assert(io.open(cname, "w")) fp:write (CFile) fp:close() execute("gcc -c " .. cname .. " -o " .. objname) os.remove(cname) end function CreateProxyDll (config) assert(type(config) == "table", "argument #1: a table expected") assert(config.PROXY, "config.PROXY not specified") assert(config.HOST, "config.HOST not specified") assert(config.DEFFILE, "config.DEFFILE not specified") assert(io.open(config.HOST)):close() assert(io.open(config.DEFFILE)):close() ----------------------------------------------------------------------------- local hostpath, hostname = config.HOST:match ("^(.+)[\\/](.+)$") if not hostpath then hostpath, hostname = ".", config.HOST end local temp_dll = (hostname:sub(-4):lower() ~= ".dll") and "temp_dll.dll" local temp_obj = "temp_obj.o" CreateObjectFile(temp_obj) local cmdline = table.concat ({ "gcc -shared -s -nostdlib", temp_obj, config.DEFFILE, "-L" .. (temp_dll and "." or hostpath), "-l" .. (temp_dll or hostname):sub(1,-5), "-o" .. config.PROXY, }, " ") if temp_dll then execute("copy " .. config.HOST .. " " .. temp_dll) end execute(cmdline) os.remove(temp_obj) if temp_dll then os.remove(temp_dll) end end
以下构建适用于 MSVC2005。它使用“nodefaultlib”链接器选项。最终的代理 DLL 大约为 9 KB。
local DEFFILE = "lua5.1.def" -- .def file for lua5.1.dll local LIBFILE = "lua5.1.lib" -- .lib file for lua5.1.dll local CFILE = "luaproxy.c"-- output file local MAKFILE = "luaproxy.mak" -- output file ---------------------------------------------------------------------- local cfile = assert(io.open(CFILE, "w")) cfile:write [=[ #include <windows.h> BOOL APIENTRY DllMain(HANDLE module, DWORD reason, LPVOID reserved) { return TRUE; } ]=] cfile:close() ---------------------------------------------------------------------- local makfile = assert(io.open(MAKFILE, "w")) makfile:write(string.format([=[ lua51.dll : luaproxy.c cl -I../lua/src /O2 /LD /GS- luaproxy.c /link /def:%s %s \ /out:lua51.dll /nodefaultlib /entry:DllMain ]=], DEFFILE, LIBFILE)) makfile:close() ----------------------------------------------------------------------
似乎您正在做的是构建一个空的 C 文件,它链接到导入库中的存根,并将这些存根重新公开为 dll 接口。这意味着您生成的 DLL
如果我误解了你的代码,请告诉我。