खोज…


वाक्य - विन्यास

  • lua_State * L = lua_open (); // एक नया वीएम राज्य बनाएं; लुआ 5.0
  • lua_State * L = luaL_newstate (); // एक नया वीएम राज्य बनाएं; लुआ 5.1+
  • int luaL_dofile (lua_State * L, const char * filename ); // निर्दिष्ट lua_State का उपयोग करके दिए गए फ़ाइल नाम के साथ एक लुआ स्क्रिप्ट चलाएँ
  • शून्य luaL_openlibs (lua_State * L); // सभी मानक पुस्तकालयों को निर्दिष्ट lua_State में लोड करें
  • शून्य lua_close (lua_State * L); // VM राज्य बंद करें और अंदर कोई संसाधन जारी करें
  • void lua_call (lua_State * L, int nargs, int nresults); // luavalue को इंडेक्स पर कॉल करें - (nargs + 1)

टिप्पणियों

Lua साथ ही यह वर्चुअल मशीन को एक उचित C API प्रदान करता है। VM के विपरीत, C API इंटरफ़ेस स्टैक आधारित है। इसलिए, डेटा के साथ उपयोग किए जाने वाले अधिकांश फ़ंक्शन या तो वर्चुअल स्टैक के कुछ सामान जोड़ रहे हैं, या इसे हटा रहे हैं। इसके अलावा, सभी एपीआई कॉल को स्टैक के भीतर सावधानी से उपयोग किया जाना चाहिए और यह सीमाएं हैं।

सामान्य तौर पर, Lua भाषा पर उपलब्ध कुछ भी इसे C API का उपयोग करके किया जा सकता है। इसके अलावा, कुछ अतिरिक्त कार्यक्षमता भी है जैसे कि आंतरिक रजिस्ट्री तक सीधे पहुंच, मानक मेमोरी एलोकेटर या कचरा कलेक्टर का व्यवहार बदलना।

आप अपने टर्मिनल पर निम्नलिखित निष्पादित करके Lua C API उदाहरणों को संकलित कर सकते हैं:

$ gcc -Wall ./example.c -llua -ldl -lm

लुआ वर्चुअल मशीन बनाना

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

int main(void)
{
5.1
  /* Start by creating a new VM state */
  lua_State *L = luaL_newstate();

  /* Load standard Lua libraries: */
  luaL_openlibs(L);
5.1
  /* For older version of Lua use lua_open instead */
  lua_State *L = lua_open();

  /* Load standard libraries*/
  luaopen_base(L);
  luaopen_io(L);
  luaopen_math(L);
  luaopen_string(L);
  luaopen_table(L);
    /* do stuff with Lua VM. In this case just load and execute a file: */
    luaL_dofile(L, "some_input_file.lua");

    /* done? Close it then and exit. */
    lua_close(L);

    return EXIT_SUCCESS;
}

लुआ कार्यों को कॉल करना

#include <stdlib.h>

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

int main(void)
{
    lua_State *lvm_hnd = lua_open();
    luaL_openlibs(lvm_hnd);

    /* Load a standard Lua function from global table: */
    lua_getglobal(lvm_hnd, "print");

    /* Push an argument onto Lua C API stack: */
    lua_pushstring(lvm_hnd, "Hello C API!");

    /* Call Lua function with 1 argument and 0 results: */
    lua_call(lvm_hnd, 1, 0);

    lua_close(lvm_hnd);

    return EXIT_SUCCESS;
 }

ऊपर के उदाहरण में हम ये काम कर रहे हैं:

  • पहले उदाहरण में दिखाए गए अनुसार Lua VM को बनाना और स्थापित करना
  • वर्चुअल स्टैक पर वैश्विक Lua तालिका से एक Lua फ़ंक्शन प्राप्त करना और धकेलना
  • वर्चुअल स्टैक पर इनपुट तर्क के रूप में स्ट्रिंग "Hello C API" को धकेलना
  • वीएम को एक तर्क के साथ एक फ़ंक्शन को कॉल करने का निर्देश देना जो पहले से ही स्टैक पर है
  • बंद करना और सफाई करना

ध्यान दें:

ध्यान में रखते हुए, कि lua_call() फ़ंक्शन को पॉप करता है और यह केवल परिणाम छोड़ने वाले स्टैक से तर्क देता है।

इसके अलावा, यह Lua संरक्षित कॉल - lua_pcall() बजाय सुरक्षित होगा।

कस्टम एपीआई और लुआ अनुकूलन के साथ एंबेडेड लुआ दुभाषिया

सी कोड में एक लुआ दुभाषिए को एम्बेड करने के तरीके का प्रदर्शन करें, लुआ लिपि में एक सी-परिभाषित फ़ंक्शन को उजागर करें, एक लुआ लिपि का मूल्यांकन करें, लुआ से एक सी-परिभाषित फ़ंक्शन को कॉल करें, और सी (होस्ट) से एक लुआ-परिभाषित फ़ंक्शन को कॉल करें।

इस उदाहरण में, हम चाहते हैं कि मूड एक लुआ स्क्रिप्ट द्वारा निर्धारित किया जाए। यहाँ मूड है।

-- Get version information from host
major, minor, build = hostgetversion()
print( "The host version is ", major, minor, build)
print("The Lua interpreter version is ", _VERSION)

-- Define a function for host to call
function mood( b )

    -- return a mood conditional on parameter
    if (b and major > 0) then
        return 'mood-happy'
    elseif (major == 0) then
        return 'mood-confused'
    else
        return 'mood-sad'
    end
end

सूचना, mood() को स्क्रिप्ट में नहीं कहा जाता है। यह बस होस्ट एप्लिकेशन को कॉल करने के लिए परिभाषित किया गया है। यह भी ध्यान रखें कि स्क्रिप्ट एक फ़ंक्शन को hostgetversion() जिसे स्क्रिप्ट में परिभाषित नहीं किया गया है।

अगला, हम एक मेजबान एप्लिकेशन को परिभाषित करते हैं जो 'मूड.लुआ' का उपयोग करता है। यहाँ 'hostlua.c' है:

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

/* 
 * define a function that returns version information to lua scripts
 */
static int hostgetversion(lua_State *l)
{
    /* Push the return values */
    lua_pushnumber(l, 0);
    lua_pushnumber(l, 99);
    lua_pushnumber(l, 32);

    /* Return the count of return values */
    return 3;
}

int main (void)
{
    lua_State *l = luaL_newstate();
    luaL_openlibs(l);

    /* register host API for script */
    lua_register(l, "hostgetversion", hostgetversion);

    /* load script */
    luaL_dofile(l, "mood.lua");

    /* call mood() provided by script */
    lua_getglobal(l, "mood");
    lua_pushboolean(l, 1);
    lua_call(l, 1, 1);

    /* print the mood */
    printf("The mood is %s\n", lua_tostring(l, -1));
    lua_pop(l, 1);

    lua_close(l);
    return 0;
}

और यहाँ उत्पादन है:

The host version is     0    99    32
Lua interpreter version is     Lua 5.2
The mood is mood-confused

हमारे पास 'hostlua.c' संकलित करने के बाद भी, हम अपने प्रोग्राम के आउटपुट को बदलने के लिए 'mood.lua' को संशोधित करने के लिए स्वतंत्र हैं!

तालिका में हेरफेर

किसी तालिका पर किसी इंडेक्स को एक्सेस या बदलने के लिए, आपको किसी तरह टेबल को स्टैक में रखने की आवश्यकता है।
आइए मान लें, इस उदाहरण के लिए कि आपकी तालिका एक वैश्विक चर है जिसका नाम tbl है।

किसी विशेष इंडेक्स पर सामग्री प्राप्त करना:

int getkey_index(lua_State *L)
{
  lua_getglobal(L, "tbl");    // this put the table in the stack
  lua_pushstring(L, "index"); // push the key to access
  lua_gettable(L, -2);        // retrieve the corresponding value; eg. tbl["index"]

  return 1;                   // return value to caller
}

जैसा कि हमने देखा है, आपको बस इतना करना है कि तालिका को स्टैक में धकेलना है, सूचकांक को धक्का देना है और lua_ अविस्मरणीय कॉल करना है। -2 तर्क का अर्थ है कि स्टैक के शीर्ष से तालिका दूसरा तत्व है।
lua_ अविस्मरणीय ट्रिगर्स मेटामेथोड्स। यदि आप मेटामेथोड्स को ट्रिगर नहीं करना चाहते हैं, तो इसके बजाय lua_rawget का उपयोग करें। यह उसी तर्कों का उपयोग करता है।

किसी विशेष इंडेक्स पर सामग्री सेट करना:

int setkey_index(lua_State *L)
{
  // setup the stack
  lua_getglobal(L, "tbl");
  lua_pushstring(L, "index");
  lua_pushstring(L, "value");
  // finally assign the value to table; eg. tbl.index = "value"
  lua_settable(L, -3);

  return 0;
}

सामग्री के रूप में एक ही ड्रिल। आपको स्टैक को पुश करना है, इंडेक्स को पुश करना है और फिर स्टैक में मान को पुश करना है। उसके बाद, आप lua_settable कहते हैं। -3 तर्क स्टैक में तालिका की स्थिति है। मेटामेथोड्स को ट्रिगर करने से बचने के लिए, lua_settable के बजाय lua_rawset का उपयोग करें। यह उसी तर्कों का उपयोग करता है।

तालिका से सामग्री को दूसरे में स्थानांतरित करना:

int copy_tableindex(lua_State *L)
{
    lua_getglobal(L, "tbl1"); // (tbl1)
    lua_getglobal(L, "tbl2");// (tbl1)(tbl2)
    lua_pushstring(L, "index1");// (tbl1)(tbl2)("index1")
    lua_gettable(L, -3);// (tbl1)(tbl2)(tbl1.index1)
    lua_pushstring(L, "index2");// (tbl1)(tbl2)(tbl1.index1)("index2")
    lua_pushvalue(L, -2); // (tbl1)(tbl2)(tbl1.index1)("index2")(tbl1.index1)
    lua_settable(L, -4);// (tbl1)(tbl2)(tbl1.index1)
    lua_pop(L, 1);

    return 0;
}

अब हम यहां सीखे गए सभी को एक साथ रख रहे हैं। मैंने टिप्पणियों पर स्टैक सामग्री डाल दी है ताकि आप खो न जाएं।

हम दोनों तालिकाओं को स्टैक में डालते हैं, तालिका 1 के सूचकांक को स्टैक में tbl1.index1 , और tbl1.index1 पर मान प्राप्त करते हैं। ध्यान देने योग्य पर -3 तर्क ध्यान दें। मैं पहली तालिका देख रहा हूं (ऊपर से तीसरा) और दूसरा नहीं। फिर हम दूसरी तालिका के सूचकांक को धक्का देते हैं, स्टैक के शीर्ष पर tbl1.index1 प्रतिलिपि tbl1.index1 और फिर शीर्ष से 4 आइटम पर lua_settable कहते हैं।

गृहकार्य के लिए, मैंने शीर्ष तत्व को शुद्ध कर दिया है, इसलिए स्टैक पर केवल दो टेबल बने हुए हैं।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow