如何修补或替换Lua中的函数(具有恢复能力)

时间:2015-12-03 02:47:02

标签: lua

我想我错过了代码中的一些内容,要么我的“伪代码”不正确,要么函数不能通过引用传递给Lua ..
我只想要一个小型库,它允许我用另一个函数修补/替换一个函数,但能够将修补后的函数恢复到原来的函数。

也许,过去有人已经制作了这样的图书馆(我找不到它)
我目前的代码:

--[[
When user wants to patch/replace/detour a variable of type "function" to equal to another variable of type "function", we should always first check user's input, that is the following question - have user supplied valid arguments.
If invalid argument is caught, then throw an error to the user.
Now we know that user have supplied valid arguments, next we should check if supplied function (that is to be patched) is already patched function, if it is then throw an error to the user.
Now we save supplied function (the one to be patched) in a global table (to allow user to restore it later using another function).
Finally, we assign a function (the one to be patched) to the second function that user have supplied.


When user wants to restore original function, we should again check user's input first, that is, have user supplied a function and if so - is it really patched.
Now we know that user have supplied valid argument, so lets restore original function by looking-up in a global table (where we saved original function).
If by any chance original function is not found, just throw an error to the user.
We have all information at this point, assign a patched function (from user's input) to the original function.
Finally, clean-up, remove original function information from our global table (as it is no longer patched).
--]]

ftbl = ftbl or {}

patchf = function(dest, src)
    assert(type(dest) == "function", "bad argument #1 (function expected, got " .. type(dest) .. ")")
    assert(type(src) == "function", "bad argument #2 (function expected, got " .. type(src) .. ")")
    assert(not ftbl[src], "destination is already patched/same source exists")
    ftbl[src] = dest
    dest = src
end

restoref = function(src)
    assert(type(src) == "function", "bad argument #1 (function expected, got " .. type(src) .. ")")
    assert(type(ftbl[src]) == "function", "source is not patched/source does not exists")
    fsrc = ftbl[src]
    ftbl[src] = nil
end

local my_function = function()
  print("Hello from my_function :D", 1)
end

local another_function = function()
  print("Hello from another_function D:", 2)
end

patchf(another_function, my_function)

another_function() -- Hello from another_function D:    2

正如您所看到的,它没有使用my_function修补another_function。

1 个答案:

答案 0 :(得分:0)

  

任何想法如何使它适用于本地功能(如下所示)   当前代码)?

您不需要用于通过其他本地函数替换本地函数的库。只需做一个简单的赋值操作。

例如:

local fu = function()
    print "fu"
end

local fu_new = function()
    print "new fu"
end

fu()
fu, fu_new = fu_new, fu
fu()
fu, fu_new = fu_new, fu
fu()

将输出:

fu
new fu
fu