2015-12-03 35 views
1

我認爲我錯過了代碼中的某些東西,要麼是我的「僞代碼」不正確,要麼函數沒有通過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

你的問題正是LUA ** **是通過引用傳遞的功能。當您運行'dest = src'時,您不會分配給全局變量'another_function'。你正在分配給本地函數'dest'。您需要分配給全局來替換全局值。 –

+0

@EtanReisner好的。現在我猜測我需要對patchf進行更改,而不是採用函數,我可以使其來自_G的「路徑」字符串,但這隻適用於全局函數。任何想法如何使它在本地函數上工作(如在當前代碼中所見)?調試庫?呃..還是我錯了? – user5219043

+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 
+0

然後你將如何修補在其他Lua文件中定義的局部函數(超出範圍)......看看我在做這樣一個庫的意義。你在做什麼只是在這裏不是一個解決方案(不是試圖進攻,但你只是告訴我什麼,我已經知道)...這從一個簡單的任務升級到300線(問題中的代碼已過時)。附:我已經完成了修補程序,現在需要恢復:D – user5219043