Created
January 9, 2014 07:08
-
-
Save moteus/8330491 to your computer and use it in GitHub Desktop.
Create proxy dll library on Windows.
This script use `dumpbin` to list all export symbols.
Example: `mkforwardlib lua51 lua5.1 X86` create lua5.1.dll as proxy to lua51.dll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local reallib | |
local fakelib | |
local machine | |
local extrasymbols = {} | |
local args = {...} | |
local errmsg | |
if args[1] then reallib = args[1] end | |
if args[2] then fakelib = args[2] end | |
if args[3] then machine = args[3] end | |
for i=4,#args do | |
table.insert(extrasymbols, args[i]) | |
end | |
if #args<3 then | |
errmsg = "not enough parameters" | |
elseif not ({X86=true, AMD64=true, IA64=true})[machine] then | |
errmsg = "'"..machine.."' is not a recognized machine architecture" | |
end | |
if errmsg then | |
if errmsg then io.stderr:write("Error: "..errmsg.."\n") end | |
io.stderr:write[[ | |
Usage: mkforwardlib <reallib> <fakelib> <machine> [<extrasymbols>...] | |
reallib The name of the existing dll that you want to use. | |
fakelib The name of the fake dll that you want to create and that | |
will call the reallib instead. | |
machine The hardware architecture of your windows version among: | |
X86, AMD64, IA64 | |
extrasymbols Additionnal symbols to export beyond standard Lua symbols | |
(if you have a very custom Lua dll). | |
Example: mkforwardlib lua51 lua5.1 X86 | |
]] | |
-- :TODO: add support for AM33, ARM, CEE, EBC, M32R, MIPS, MIPS16, MIPSFPU, MIPSFPU16, MIPSR41XX, SH4, SH5, THUMB | |
os.exit(0) | |
end | |
local VisualC = os.getenv('VCPATH') | |
if not VisualC then | |
if machine=='AMD64' then | |
local PlatformSDK = assert(os.getenv"MSSDK", "MSSDK environment variable is not set, please set it to the path to your Platform SDK") | |
VisualC = PlatformSDK.."\\Bin\\win64\\x86\\AMD64" | |
elseif machine=='IA64' then | |
local PlatformSDK = assert(os.getenv"MSSDK", "MSSDK environment variable is not set, please set it to the path to your Platform SDK") | |
VisualC = PlatformSDK.."\\Bin\\win64" | |
else | |
-- local VisualCRoot = (os.getenv"PROGRAMFILES(X86)" or os.getenv"PROGRAMFILES").."\\Microsoft Visual Studio .NET 2003\\Vc7" | |
local VisualCRoot = (os.getenv"PROGRAMFILES(X86)" or os.getenv"PROGRAMFILES").."\\Microsoft Visual Studio 8\\VC" | |
VisualC = VisualCRoot.."\\bin" | |
end | |
end | |
function file_temp() | |
local res = os.tmpname() | |
res = os.getenv'TMP' .. res .. 'tmp' | |
return res | |
end | |
function execute (cmd) | |
local res1,res2,res2 = os.execute(cmd) | |
if not lua52 then | |
return res1==0,res1 | |
else | |
return res1,res2 | |
end | |
end | |
function execute_wrapper (cmd,callback) | |
local tmpfile = file_temp() | |
local ok,code = execute(cmd..' >"' .. tmpfile .. '" 2>&1') | |
local inf = io.open(tmpfile, 'r') | |
callback(ok,code,inf) | |
if inf then inf:close() end | |
os.remove(tmpfile) | |
end | |
function get_exports(fname) | |
local ret, err | |
local cmd = 'dumpbin /EXPORTS "' .. fname .. '"' | |
local fn_pat = "^%s+%d+%s+[0-9A-F]+%s+[0-9A-F]+%s+(%S+)%s*$" | |
execute_wrapper(cmd, function(status, code, f) | |
err = code | |
if not status then return end | |
ret = {} | |
for str in f:lines() do | |
local fn = string.match(str,fn_pat) | |
if fn then table.insert(ret, fn) end | |
end | |
end) | |
return ret, err | |
end | |
local symbols = assert(get_exports(reallib .. '.dll'), 'Can not load reallib: ' .. reallib .. '.dll') | |
local link = '"'..VisualC..'\\link.exe"' | |
local command = { | |
" -dll", | |
" -nologo", | |
" -noentry", | |
" -machine:"..machine, | |
" -incremental:no", | |
" -nodefaultlib", | |
" -out:"..fakelib..".dll", | |
" -implib:"..fakelib..".lib", | |
} | |
for _,symbol in ipairs(symbols) do | |
table.insert(command," /export:"..symbol.."="..reallib.."."..symbol) | |
end | |
for _,symbol in ipairs(extrasymbols) do | |
table.insert(command," /export:"..symbol.."="..reallib.."."..symbol) | |
end | |
local tmpName = os.tmpname() | |
local tmpFile = io.open(tmpName,'w') | |
tmpFile:write(table.concat(command)) | |
tmpFile:close() | |
local ok,ret = pcall(os.execute, '"'..link.. ' @'.. tmpName ..'"') | |
os.remove(tmpName); | |
if ok then | |
os.exit(ret) | |
else | |
error(ret) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment