2011-01-28 23 views
6

Tôi muốn người dùng ứng dụng C++ của tôi có thể cung cấp các chức năng ẩn danh để thực hiện các khối công việc nhỏ.Làm cách nào để tải một hàm chưa được đặt tên trong Lua?

Các mảnh nhỏ như thế này sẽ lý tưởng.

function(arg) return arg*5 end 

Bây giờ tôi muốn để có thể viết một cái gì đó đơn giản như này cho mã C của tôi,

// Push the function onto the lua stack 
lua_xxx(L, "function(arg) return arg*5 end") 
// Store it away for later 
int reg_index = luaL_ref(L, LUA_REGISTRY_INDEX); 

Tuy nhiên tôi không nghĩ rằng lua_loadstring sẽ làm "điều đúng đắn".

Tôi còn lại với những gì cảm thấy với tôi như một hack khủng khiếp?

void push_lua_function_from_string(lua_State * L, std::string code) 
{ 
    // Wrap our string so that we can get something useful for luaL_loadstring 
    std::string wrapped_code = "return "+code; 
    luaL_loadstring(L, wrapped_code.c_str()); 
    lua_pcall(L, 0, 1, 0); 
} 

push_lua_function_from_string(L, "function(arg) return arg*5 end"); 
int reg_index = luaL_ref(L, LUA_REGISTRY_INDEX); 

Có giải pháp nào tốt hơn không?

Trả lời

7

Nếu bạn cần quyền truy cập vào thông số, cách bạn đã viết là chính xác. lua_loadstring trả về một hàm đại diện cho đoạn mã/mã bạn đang biên dịch. Nếu bạn muốn thực sự nhận được một hàm từ mã, bạn phải return nó. Tôi cũng làm điều này (ở Lua) cho những "người đánh giá biểu hiện", và tôi không coi đó là "hack khủng khiếp" :)

Nếu bạn chỉ cần một số cuộc gọi lại, không có tham số, bạn có thể viết mã trực tiếp và sử dụng hàm trả về lua_tostring. Bạn thậm chí có thể chuyển các tham số cho đoạn này, nó sẽ có thể truy cập như biểu thức .... Sau đó, bạn có thể nhận được các thông số như:

local arg1, arg2 = ... 
-- rest of code 

Bạn quyết định điều gì tốt hơn cho bạn - "mã xấu xí" bên trong mã thư viện của bạn hoặc "mã xấu xí" trong hàm Lua của bạn.

+0

Tôi cũng đã quyết định không hoàn toàn bị hack như cảm giác của tôi. Và kể từ khi người dùng cuối sẽ được viết các hàm lua, tôi nghĩ rằng hack "không quá khủng khiếp" của tôi là cách duy nhất để đi. –

+0

Michal đã đúng. Các "chunk" có thể chấp nhận đối số nhưng cần sự trở lại. – mlepage

3

Hãy xem ae của tôi. Nó lưu trữ các hàm từ các biểu thức để bạn có thể chỉ cần nói ae_eval("a*x^2+b*x+c") và nó sẽ chỉ biên dịch nó một lần.

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