2012-07-27 16 views
5

के बीच साझा ऐरे मैंने वास्तव में इस प्रश्न को गुगल किया है लेकिन मुझे वास्तव में कोई समाधान नहीं मिला।लुआ और सी

मैं प्रदर्शन के लिए सी और लुआ के बीच एक ऐरे साझा करना चाहता हूं, मैं लूआ से और उसके लिए Arrays की प्रतिलिपि बनाने से बचूंगा।

तो मैं सी से लुआ तक ऐरे में एक पॉइंटर पास करना चाहता हूं। और फिर लुआ से मैं सीधे इस सरणी में मूल्यों को सेट/संशोधित करना चाहता हूं। सी कोड में


उदाहरण

मैं अपने सरणी यह ​​वैश्विक नाम mydata साथ लुआ से उस तक पहुंच

int mydata[] = {1,2,3,4} 

सेट को परिभाषित करना चाहते हैं।


लुआ

में मैं इस

mydata[3] = 9 

तरह मूल्यों को बदलना चाहते हैं और जब मैं सी पर लौटने, mydata[3] 9 है, क्योंकि यह सरणी के लिए सूचक है।

यह कैसे संभव है?

+0

के बाद से lua सी के साथ अच्छी तरह से इंटरफेस करने किसी एम्बेड भाषा के रूप में करना है, मैं lua प्रलेखन पर्याप्त उदाहरण प्रदान करने की उम्मीद होगी। क्या आपने पहले ही इस जानकारी को ब्राउज़ किया था? – Jens

+0

एक तेज़ उत्तर के लिए धन्यवाद। मैंने लगभग किसी दस्तावेज़ को देखा है, लेकिन मुझे सरणी के लिए सूचक के साथ उदाहरण नहीं मिल सकते हैं। – user1557786

+0

यह लुआ नहीं है, लुआ नहीं। यह एक संक्षिप्त नाम नहीं है; यह एक नाम है। –

उत्तर

19

आप userdata के माध्यम से लुआ को मनमानी डेटा का खुलासा कर सकते हैं। यदि आप अपने उपयोगकर्ता डेटा को मेटाटेबल मान देते हैं, तो आप उन उपयोगकर्ता डेटा पर विभिन्न ऑपरेटरों/संचालन के व्यवहार को परिभाषित कर सकते हैं। इस मामले में, हम लुआ को एक सरणी का खुलासा करना चाहते हैं और परिभाषित करना चाहते हैं कि array[index] और array[index] = value के मामले में क्या करना है।

हम सरणी के पते को पकड़ने के लिए पर्याप्त उपयोगकर्ता डेटाटा बफर बनाकर लू को सरणी का पर्दाफाश करते हैं। हम __index और __newindex विधियों के साथ मेटाटेबल बनाए गए अनुक्रमण/असाइनमेंट व्यवहार को परिभाषित करते हैं।

नीचे एक पूर्ण, कामकाजी उदाहरण है जो लुआ को एक स्थिर सरणी का खुलासा करता है। आपके कार्यक्रम में शायद लुआ को सरणी लौटने के लिए कुछ अन्य कॉल होगा। ध्यान दें, बिल्कुल कोई सीमा नहीं है; यदि आप सरणी सीमाओं के बाहर इंडेक्स करने का प्रयास करते हैं, तो आप क्रैश हो जाएंगे। इसे और अधिक मजबूत बनाने के लिए, आप उपयोगकर्ता डेटा को उस संरचना में बदलना चाहते हैं जिसमें सरणी सूचक और सरणी आकार है, ताकि आप बाउंडशेकिंग कर सकें।

#include "lauxlib.h" 

// metatable method for handling "array[index]" 
static int array_index (lua_State* L) { 
    int** parray = luaL_checkudata(L, 1, "array"); 
    int index = luaL_checkint(L, 2); 
    lua_pushnumber(L, (*parray)[index-1]); 
    return 1; 
} 

// metatable method for handle "array[index] = value" 
static int array_newindex (lua_State* L) { 
    int** parray = luaL_checkudata(L, 1, "array"); 
    int index = luaL_checkint(L, 2); 
    int value = luaL_checkint(L, 3); 
    (*parray)[index-1] = value; 
    return 0; 
} 

// create a metatable for our array type 
static void create_array_type(lua_State* L) { 
    static const struct luaL_reg array[] = { 
     { "__index", array_index }, 
     { "__newindex", array_newindex }, 
     NULL, NULL 
    }; 
    luaL_newmetatable(L, "array"); 
    luaL_openlib(L, NULL, array, 0); 
} 

// expose an array to lua, by storing it in a userdata with the array metatable 
static int expose_array(lua_State* L, int array[]) { 
    int** parray = lua_newuserdata(L, sizeof(int**)); 
    *parray = array; 
    luaL_getmetatable(L, "array"); 
    lua_setmetatable(L, -2); 
    return 1; 
} 

// test data 
int mydata[] = { 1, 2, 3, 4 }; 

// test routine which exposes our test array to Lua 
static int getarray (lua_State* L) { 
    return expose_array(L, mydata); 
} 

int __declspec(dllexport) __cdecl luaopen_array (lua_State* L) { 
    create_array_type(L); 

    // make our test routine available to Lua 
    lua_register(L, "array", getarray); 
    return 0; 
} 

उपयोग:

require 'array' 

foo = array() 
print(foo) -- userdata 

-- initial values set in C 
print(foo[1]) 
print(foo[2]) 
print(foo[3]) 
print(foo[4]) 

-- change some values 
foo[1] = 2112 
foo[2] = 5150 
foo[4] = 777 

-- see changes 
print(foo[1]) 
print(foo[2]) 
print(foo[3]) 
print(foo[4]) 
+0

वाह मैं कामकाजी उदाहरणों के साथ इस शानदार पोस्ट के लिए आपको धन्यवाद नहीं दे सकता। यही वह है जिसे मैं फिर से धन्यवाद चाहता हूं! मैं इस मंच के लिए नया हूं मैं आपको अंक कैसे दे सकता हूं?शुरुआती लोगों के लिए – user1557786

+1

, जैसे कि मैंने वास्तव में लुइबिंद के उपयोग की आसानी की सराहना की - आपके बस मुद्दे के लिए आप देखते हैं कि इसे सीधे लुआ में करने के लिए बहुत सारे कोड की आवश्यकता होती है - लुबाइंड के साथ, मूल रूप से एक लाइनर - आपको इसे देखना चाहिए यहां एक महान परिचय है http://blog.nuclex-games.com/tutorials/cxx/luabind-introduction/ - चीजों के साथ अधिक आरामदायक होने के बाद, सीधे लुआ में विकसित करना अभी भी बेहतर है - हालांकि लुबाइंड के साथ आप मूल रूप से कर सकते हैं कामकाजी अवधारणा पाने के लिए बहुत सारी चीज़ें बहुत तेज़ हैं – Steve