2010-05-25 52 views
8

Giả sử tôi đăng ký nhiều tên hàm khác nhau trong Lua với cùng chức năng trong C. Bây giờ, mọi hàm C của tôi được gọi, có cách nào để xác định tên hàm nào được gọi không?Nhận lệnh lua khi hàm c được gọi là

ví dụ:

int runCommand(lua_State *lua) 
{ 
    const char *name = // getFunctionName(lua) ? how would I do this part 
    for(int i = 0; i < functions.size; i++) 
    if(functions[i].name == name) 
     functions[i].Call() 
} 

int main() 
{ 
    ... 

    lua_register(lua, "delay", runCommand); 
    lua_register(lua, "execute", runCommand); 
    lua_register(lua, "loadPlugin", runCommand); 
    lua_register(lua, "loadModule", runCommand); 
    lua_register(lua, "delay", runCommand); 
} 

Vì vậy, làm thế nào để tôi có được tên của những gì từng chức năng gọi nó?

+0

Tại sao bạn muốn tất cả các hàm được ánh xạ tới cùng một thường trình? –

+0

Tôi muốn có thể gọi một hàm cũng có con trỏ này, nhưng với hệ thống hiện tại, tôi chỉ có thể gọi các hàm tĩnh/toàn cục. –

Trả lời

11

Một cách khác để tấn công câu hỏi của bạn là sử dụng upvalues. Về cơ bản, bạn có đăng ký chức năng C với chức năng dưới đây thay vì lua_register:

void my_lua_register(lua_State *L, const char *name, lua_CFunction f) 
{ 
     lua_pushstring(L, name); 
     lua_pushcclosure(L, f, 1); 
     lua_setglobal(L, name); 
} 

Sau đó, getFunctionName là thẳng về phía trước

const char* getFunctionName(lua_State* L) 
{ 
    return lua_tostring(L, lua_upvalueindex(1)); 
} 

Điều đó nói rằng, những gì bạn đang cố gắng làm dường như tanh - những gì bạn đang cố gắng để đạt được? Các chức năng runCommand được đăng trong câu hỏi trông giống như một cách khủng khiếp không hiệu quả để làm điều gì đó mà Lua làm cho bạn anyway.

+0

Bạn cũng có thể đặt con trỏ 'this' này vào một giá trị upvalue/closure. –

+0

Điều gì về việc sử dụng các thông số khác và số lượng thay đổi của chúng khi sử dụng giá trị cao? –

+0

@MariusK: Tôi không chắc ý bạn là gì, bạn có thể xây dựng được không? – sbk

0

Thật không may, điều đó là không thể - trong số những thứ khác, bởi vì các chức năng trong Lua không thực sự phải có một cái tên nào cả. (Xem xét: (loadstring("a=1"))() đang thực hiện một chức năng vô danh trở về từ loadstring.)

2

Bạn có thể sử dụng lua_getinfo: http://pgl.yoyo.org/luai/i/lua_getinfo

này có thể làm việc:

const char* lua_getcurrentfunction(lua_State* L) { 
    lua_Debug ar; 
    lua_getstack(L, 1, &ar); 
    lua_getinfo(L, "f", &ar); 
    return ar.name; 
} 

Có một caveat:

name: tên hợp lý cho hàm đã cho. Bởi vì các hàm trong Lua là các giá trị hạng nhất, chúng không có tên cố định: một số hàm có thể là giá trị của nhiều biến toàn cục, trong khi các hàm khác có thể chỉ được lưu trữ trong một trường bảng. Hàm lua_getinfo kiểm tra cách hàm được gọi để tìm một tên phù hợp. Nếu nó không thể tìm thấy tên, thì tên được đặt thành NULL.

2

Một giải pháp thay thế sẽ là đăng ký một metatable cho bảng môi trường Lua thực hiện các cuộc gọi hàm số __index này.

0

Nếu bạn sẵn sàng thu thập được tất cả hành chức năng không rõ, bạn có thể chơi trò chơi với setmetatablecurrying:

 
    -- This function would not be in lua in your example, 
    -- you'd be doing lua_register(lua, "runCommandNamed", runCommandNamed) 
    -- and writing a runCommandNamed in C. 
    function runCommandNamed(cmd, ...) 
     print("running command", cmd, "with arguments", ...) 
    end 

    -- The rest would be somewhere in lua-land: 
    local utilMetaTable = { 
     __index = function (t, key) 
      return function(...) -- mmm, curry 
       runCommandNamed(key, ...) 
      end 
     end 
    } 

    _util = {} 
    setmetatable(_util, utilMetaTable) 

    -- prints "running command CommandOne  with arguments arg1 arg2 arg3" 
    _util.CommandOne("arg1", "arg2", "arg3") 

    -- prints "running command CommandTwo  with arguments argA argB" 
    _util.CommandTwo("argA", "argB") 

Trong ví dụ này, tôi đã chỉ láp lên hành chưa biết dưới _util thay vì trong bảng toàn cầu.

+0

(Lua gurus: xin vui lòng đề xuất cú pháp hay thay đổi phong cách tốt hơn, tôi sẽ rất vui khi kết hợp chúng. Tôi không sử dụng lua tất cả thường xuyên, không may, mặc dù là một trong đó tích hợp nó vào động cơ của chúng tôi tại nơi làm việc.) – leander

Các vấn đề liên quan