【问题标题】:Lua - Function That Creates DetoursLua - 创建弯路的函数
【发布时间】:2015-06-05 01:01:48
【问题描述】:

我需要对各种功能绕道而行,一个一个地做是不可行的。我正在寻找一个可以使用表格的函数,理想情况下,这个表格是类。循环遍历它,对于作为函数的每个键、值对,在原始函数名称之前创建一个带有前缀的函数指针。我尝试了几种变体来达到这种效果,但它们都会产生不同的问题。有的不管你给他们什么都不会做迂回指针,有的会做迂回指针但它们不起作用,还有一些会溢出堆栈或根本无法识别。

我想知道是否有办法,即原始集、元表覆盖、不断循环直到它们匹配等,以便函数可以获得一个表(或与表同名的字符串,因此 loadstring 方法也可以在这里工作)并循环遍历每个函数并制作一个有效的绕行指针......无论如何。

我更喜欢使用 self:prefix_orig_name(...) 语法 [... 可以替换为实际的 args]。

这是我尝试使用示例用法的 2 种变体。

-- 1st Method
detours = detours or {}

function detour(object, class) -- Class is an extra arg that I would send if for some reason just sending an object didn't work...it was theory oh'ed
    if detours[object] then -- Check if the detour already exists...might be worth remaking it especially if the function gets overridden several times in different places?
        print("detour: Previous " .. object .. " detour found, using previous detour")
        return
    end
    for name, func in pairs(class and class or loadstring("return " .. object)()) do
        -- the loadstring method here is used because the argument received is a string of the same name as the table...thus loading it will yield a table
        if type(func) == "function" then
            local execute, error = loadstring(object .. ".custom_detour_" .. name .. " = " .. object .. "." .. name) -- This makes the actual pointer
            if error then
                print("detour Error: " .. " Failed to detour: " .. object .. " Error: " .. error)
            end
            local luanch, assert = pcall(execute)
            if not luanch then
                print("detour Error: " .. " Failed to detour: " .. object .. " Error: " .. assert)
            end
        end
    end
    print("Table: " .. object .. " successfully detourd")
    detours[object] = true -- tells us we made a detour of this table/string
end

-- 2nd Method
function detour(object) -- Takes a table
    for k, v in pairs(object) do
        if type(v) == "function" and not detours[k] then
            if not object.custom_detour_ then
                object.custom_detour_ = clone(object) -- use a simple cloning function (shallow) to put a clone of the main table into a sub table of the main table
            end
            if object["custom_detour_" .. k] ~= object.custom_detour_[k] then
                object["custom_detour_" .. k] = object.custom_detour_[k] -- this makes it so the self:custom_detour_orig_name(...) syntax can be used, if I am not mistaken
            end
        end
    end
end

-- Example Usage:
MyClass = class() -- class function is relatively OOP standard

function MyClass:init()
    self._something = true
end

function MyClass:change(value)
    self._something = value
end

function MyClass:table_print(tbl) -- just making funcs up
    for k, v in pairs(tbl) do
        print(v)
    end
end

my_class = MyClass:new()

-- 1st Method
detour("MyClass")

--2nd Method
detour(MyClass)

我个人更喜欢第一种方法,或者至少是一个字符串,因为我可以记录每一个弯路,如果以后出现问题,它会使调试更容易......但我支持任何可行的方法。

【问题讨论】:

  • 我不太确定你想做什么。您是否试图让obj:custom_detour_foo() 别名obj:foo()
  • @ColonelThirtyTwo 我相信是的。我正在尝试做这样的事情function obj:foo() self:custom_detour_foo() --new stuff here like overrides/etc end

标签: class oop pointers lua clone


【解决方案1】:

简单的绕道很容易用闭包做;不需要loadstring:

function detour(cls)
    local detours = {}
    for key, value in pairs(cls) do
        if type(value) == "function" then -- note: ignores objects with __call metamethod
            detours["custom_detour_"..key] = function(...)
                -- Do whatever you want here
                return value(...)
            end
        end
    end
    for key, value in pairs(detours) do
        cls[key] = value
    end
end

【讨论】:

  • 看起来不错,但我们假设需要处理 __call 元方法……那该怎么做?我想涵盖所有可能的途径。
  • and debug.getmetatable(value).__call 添加到if 条件
  • 好的……还有其他可能被忽略或遗忘的可能性吗? --Edit:尝试这个似乎只是溢出了堆栈。
  • 好吧...如果你有一个恰好有foocustom_detour_foo 的类,那么你就会遇到问题。扫描也只发生一次;如果将新函数添加到类中,那么您将不会为它们走弯路,但这种情况极不可能发生。
  • 我在某些函数上出现堆栈溢出...为什么?
猜你喜欢
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-24
  • 2016-04-29
  • 1970-01-01
  • 2019-11-11
相关资源
最近更新 更多