2012-06-13 29 views
7

Cho phép nói rằng tôi có ít nhất hai tệp kịch bản lệnh lua.Hộp cát nhúng Lua trong 5.2/Thiết lập môi trường cho các hàm từ lua.file

test1.lua test2.lua

cả xác định một hàm init và các chức năng khác với tên tương tự.

Làm cách nào tôi có thể tải từng tệp tập lệnh bằng C++/c vào môi trường riêng bằng Lua 5.2 để các tên hàm giống nhau không bị xung đột - tôi tìm thấy mã mẫu cho 5.1 không hoạt động cho tôi (vì setenv đã biến mất và lua_setuservalue dường như không làm việc)

Sample đây Calling lua functions from .lua's using handles?

Về cơ bản nếu tôi thay setenv với setuservalue - tôi nhận được một vi phạm truy cập.

+0

Đây là một trong những lý do tại sao tôi đã bị mắc kẹt với lua 5.1 trong các dự án riêng của tôi bây giờ. Tôi tin rằng các hàm v5.2 'load' và' loadfile' cho phép bạn chỉ định một môi trường; họ có lẽ là nơi tốt nhất để bắt đầu tìm kiếm giải pháp. – Rook

+0

cảm ơn nhưng tôi đọc về tải và loadfile tuy nhiên tôi không thể tìm thấy một giải pháp – Steve

+0

'setuservalue' chắc chắn không phải là chức năng chính xác để sử dụng khi cố gắng thao tác với môi trường. Các tài liệu lua dường như không rõ ràng về những gì bạn nên làm, tuy nhiên. 'lua_load' nói rằng một upvalue duy nhất liên kết với một đoạn nạp được thiết lập như môi trường của nó, nhưng không đề cập đến cách bạn đi về liên kết một upvalue với đoạn từ C. Nếu bạn đang tải đoạn từ bên trong lua, phiên bản lua của Hàm 'load' trông giống như nó nên thiết lập môi trường một cách chính xác. – Rook

Trả lời

8

unofficial Lua FAQ có mục nhập về hộp cát ở Lua. Tôi đoán là bạn có thể chuyển đổi logic đó đủ dễ dàng tới mã C/C++ của bạn.

Xem thêm LuaFiveTo on the lua-users wiki.

Correction

Đó là thực sự không phải là tầm thường như nó có vẻ. Nhưng cuối cùng là điểm đơn giản: tải đoạn của bạn, đẩy bảng _ENV, sử dụng lua_setupvalue(L,-2,1). Điều quan trọng là bảng nên ở trên cùng của ngăn xếp.

Như một ví dụ nhỏ, sử dụng 2 môi trường mặc định cho _G để đọc những thứ qua metatables:

#include <lua.h> 
#include <lualib.h> 
#include <lauxlib.h> 

int main(void){ 
     lua_State *L = luaL_newstate(); 
     char *file1 = "file1.lua"; 
     char *file2 = "file2.lua"; 

     luaL_openlibs(L); 

     luaL_loadfile(L,file2); // S: 1 
     luaL_loadfile(L,file1); // S: 2 
     lua_newtable(L); // ENV for file 1: S: 321 
     lua_newtable(L); // ENV for file 2: S: 4321 

     //lets have each function have its metatable, where missed lookups are 
     //instead looked up in the global table _G 

     lua_newtable(L); // metatable S: 54321 
     lua_getglobal(L,"_G"); // pushes _G, which will be the __index metatable entry S: 654321 

     lua_setfield(L,-2,"__index"); // metatable on top S: 54321 
     lua_pushvalue(L,-1); // copy the metatable S: 554321 
     lua_setmetatable(L,-3); // set the last copy for env2 S: 54321 
     lua_setmetatable(L,-3); // set the original for env1 S: 4321 
     // here we end up having 2 tables on the stack for 2 environments 
     lua_setupvalue(L,1,1); // first upvalue == _ENV so set it. S: 321 
     lua_setupvalue(L,2,1); // set _ENV for file S: 21 
     // Remaining on the stack: 2 chunks with env set. 
     lua_pcall(L,0,LUA_MULTRET,0); 
     lua_pcall(L,0,LUA_MULTRET,0); 
     lua_close(L); 
     return 0; 
} 

Và đối với các tập tin 2 Lua:

-- file1.lua 
function init() 
     A="foo" 
     print("Hello from file1") 
     print(A) 
end 
init() 

-- file2.lua 
-- this shows that stuff defined in file1 will not polute the environment for file2 
print("init function is",tostring(init)) 
function init() 
     A="bar" 
     print("Hello from file2") 
     print(A) 
end 
init() 
+0

cảm ơn nhưng tôi biết các tài nguyên này - tuy nhiên im không thể tái sản xuất này trong C/C++ – Steve

+0

Thật vậy, vấn đề là các phần tử tương đương của 'load' và' loadfile' không có giao diện hoặc tài liệu dạng thẳng như vậy. Trang wiki lua-users cũng có vẻ hơi thiếu dữ liệu và chứa các tính năng không bao giờ được đưa vào thông số 5.2. – Rook

+0

jpjacobs, chúng tôi gặp nhau trong lua-irc ngày hôm nay và như tôi đã nói tôi đã nhận được giải pháp nhưng cảm ơn một lần nữa để đặt ra một ví dụ thay thế! – Steve

0

cả xác định một hàm init và các chức năng khác có tên tương tự.

Trước hết, tại sao các chức năng đó là toàn cầu? Chúng phải là cục bộ cho tập lệnh. Nếu bạn đang truy cập require chúng trong các tệp khác, chúng sẽ tạo và trả về một bảng chứa các hàm mà chúng muốn hiển thị.

Các thành ngữ hiện đại khi đòi hỏi những tập tin này là để làm một cái gì đó như thế này:

local Library = require 'library' 

Library.Func1(...) 

Vì vậy, bạn không làm ô nhiễm không gian tên Lua toàn cầu. Bạn sử dụng các biến cục bộ.

Tuy nhiên, nếu bạn nhấn mạnh vào việc sử dụng hình cầu như thế này, bạn có thể làm chính xác những gì tài liệu đã nói: thay đổi giá trị tăng đầu tiên của đoạn đã biên dịch.

Về cơ bản nếu tôi thay thế setenv bằng setuservalue - tôi nhận được vi phạm quyền truy cập.

Tất nhiên là bạn có. Đó không phải là những gì lua_setuservaluekhông.Đó là để đặt các giá trị được liên kết với userdata. Những gì bạn muốn được gọi là lua_setupvalue.

Sử dụng mã mẫu bạn trích dẫn, câu trả lời đúng sẽ là:

lua_setupvalue(L, -2, 1); 
+0

tôi vô tình tìm ra chính mình - lua_setupvalue (L, -2, 0); sự cố! - Tôi đã đi với việc sử dụng lua_setupvalue (L, -2, 1); - kiến ​​thức của tôi bị giới hạn và tôi biết chính xác những gì 1 là trong ngữ cảnh này. nhưng nó có vẻ làm việc - bây giờ là nó cũng có thể phơi bày đối tượng của tôi chỉ trong "không gian tên" này chứ không phải trong bảng toàn cầu?im sử dụng luabind để hiển thị các lớp của tôi và hiện đang sử dụng luabind :: globals (myLuaState) ["myObj"] = myObj – Steve

+0

vì "why" là các hàm toàn cầu - tôi thích tạo một hệ thống sự kiện với các script cho nhiều thực thể sử dụng cùng chữ ký chức năng init, vì các script thường không được tạo bởi các nhà phát triển, tôi muốn làm cho nó không đau và không làm phiền bất cứ ai với libaries hoặc modules - vì vậy tôi muốn chắc chắn rằng mỗi script được thực thi trong môi trường của chính nó - nó không có nguồn gốc! – Steve

+0

@Steve: Tài liệu không rõ ràng nếu hàm 'lua_setupvalue' lấy các chỉ số dựa trên không hoặc dựa trên một. Có vẻ như họ là một người. –

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