Войти
ПрограммированиеСтатьиОбщее

Введение в Lua. (2 стр)

Состояние модуля (или: Кто имеет VM?)

Первая вещь, о которой мы должны узнать - то, что lua является по существу конечным автоматом. Дополнительно, lua - виртуальная машина. Мы к этому немного вернемся (я надеюсь). Так или иначе, как только Вы подключили свой программный интерфейс к lua, Вы можете посылать команды lua через функцию  lua_dostring. Я немного забегаю вперед. Вернемся назад и начнем по порядку с интерпретатора.

Прежде всего, в значительной степени каждая функция в lua имеет дело с состоянием lua [lua state]. Это по существу определяет текущее состояние lua интерпретатора; следит за функциями, глобальными переменными и дополнительной связанной с интерпретатором информацией в этой структуре. Вы создаете состояние lua [lua state] запросом lua_open. Эта функция выглядит примерно так:

lua_State *lua_open (int initialStackSize);

Если хотите, можете думать о lua_State как о дескрипторе текущего экземпляра lua интерпретатора. Это справедливая аналогия.

Так, если мы получаем непустой указатель в lua_State, мы знаем, что lua сумел инициализироваться правильно. Это хорошо и означает, что теперь мы можем использовать lua для своих нужд. Но по умолчанию мы можем сделать совсем немного. Это если кратко.

Давайте разработаем некоторый код и используем его как отправную точку.  lua_open() описана в lua.h (Вы можете найти его в каталоге include). Так, попробуйте скомпилировать следующий фрагмент кода как win32 консольное приложение:

#include <stdio.h>
#include <lua.h>
 
int main(int argc, char* argv[ ])
{
   lua_State* luaVM = lua_open(0);
 
   if (NULL == luaVM)
   {
      printf("Error Initializing lua\n");
      return -1;
   }
 
   return 0;
}

К сожалению, это не будет работать. Если точнее, проблема в связях. Это довольно простая проблема, но одна из тех, которые обычно происходят когда Вы имеете дело с Открытыми Исходными проектами. По существу, lua был написан на чистом ANSI C. Пожалуйста обратите внимание: я сказал ANSI C. И еще обратите внимание что все файлы в библиотеке lua имеют расширение "c". Это по существу означает, что способ, которым компилятор прессует имена всех функций lua, основан на C соглашении о вызовах. Это отличается от описателей имен функций C++. Не сложно пофиксить, но немного раздражает. Чтобы излечится от этого, просто оберните *include и остальные операторы включения ссылающиеся на lua библиотечные функции в:

extern "C"
{
   //...
}

Так, что у нас получилось:

#include <stdio.h>
extern "C"
{
 #include <lua.h>
}
 
int main(int argc, char* argv[ ])
{
   lua_State* luaVM = lua_open(0);
 
   if (NULL == luaVM)
   {
      printf("Error Initializing lua\n");
      return -1;
   }
 
   return 0;
}

Легко, это кандидат на включение в ваш заголовочный файл. Компиляция этого куска кода создаст exe и запустит его на выполнение. Он ничего не делает, зато работает.

Так, сейчас Вы вероятно задумались о том, что если мы использовали оператор 'open', то соответственно нуждаемся в операторе close. И Вы были правы. lua_close() по существу закрывает состояние, которое было открыто lua_open() . Все так и есть. Формат lua_close() напоминает следующее:

void lua_close (lua_State *openState);

Мы можем завершить наш код выше, добавив это в приложение:

#include <stdio.h>

extern "C"
{
 #include <lua.h> 
}

int main(int argc, char*  argv[ ]) 
{ 
  lua_State* luaVM = lua_open(0);

  if( NULL == luaVM ) 
  {
    printf("Error Initializing lua\n");
    return -1; 
  } 

  // Используем lua.
    
  lua_close( luaVM );
 
  return 0;
}

И, вуаля, мы имеем совершенно бесполезное lua приложение. Но, мы имеем всего лишь зародыш с полностью внедренной скрипт-системой.

Выполнение чего-нибудь полезного.

Достаточно настроек, добавим немного функционала. У нас есть всё для того, чтобы создать интерпретатор. В следующем разделе я постараюсь сосредоточится на очень простом интерпретаторе. Никакого редактора, никакой встроенной отладки, только консоль, которая позволит нам печатать команды lua и смотреть на результаты интерпретатора. Нам потребуется узнать еще одну lua функцию:  lua_dostring(). По существу, эта функция выполняет действия в lua. Я не знаю, как по другому объяснить, проще взглянуть на фрагмент кода:

#include <stdio.h>

extern "C"
{
 #include <lua.h>
} 

int main(int argc, char* argv[ ])
{ 
  lua_State* luaVM = lua_open(0); 
  if( NULL == luaVM )
  {
    printf("Error Initializing lua\n");
    return -1;
  }

  // Используем lua.
    
  char* strLuaInput = "a = 1 + 1;\n";
 
  lua_dostring(luaVM, strLuaInput);
 
  lua_close(luaVM);   
 
  return 0;
}

Выполнение и компилирование этого приложения вернет следующее:

Изображение

Это совершенно, абсолютно … бесполезно. И что нам сделать, чтобы это стало менее бесполезно? Хорошо, если Вы сползали и скачали lua или видали другие примеры lua, Вам наверное попалась на глаза функция print. Итак, добавим ее в код и возьмем в оборот. Вот код, который мы использовали бы.

#include <stdio.h>

extern "C"
{
 #include <lua.h>
} 

int main(int argc, char* argv[ ]) 
{ 
  lua_State* luaVM = lua_open(0);
  if (NULL == luaVM) 
  {
    printf("Error Initializing lua\n");
    return -1;
  } 

   // Используем lua.
    
   char* strLuaInput = "a = 1 + 1;\nprint( a);\n";
 
   lua_dostring(luaVM, strLuaInput);
 
   lua_close(luaVM);   
 
   return 0;
}

Компиляция не имеет проблем, а вот выполнение это уже другая история:

Изображение

Так в чем же дело? Я лгал? Мне кажется, прежде всего, это сообщение означает, что функция 'print' является нулевым (читайте как: пустой указатель) значением. Есть ли фактически функция с именем  print() ? Да, есть, но она не определена как стандартная в среде lua. Нам необходима связь используемой библиотеки с нашим приложением. Этот механизм, по существу, расширение lua для наших собственных эгоистичных целей. Так или иначе, мы можем заставить работать print() и некоторые другие уместные функции, следующим образом:

#include <stdio.h>

extern "C"
{
 #include <lua.h>
} 

int main(int argc, char* argv[ ]) 
{ 
  lua_State* luaVM = lua_open(0);
  if (NULL == luaVM) 
  {
    printf("Error Initializing lua\n");
    return -1;
  } 

  // инициализация стандартных библиотечных функции lua
  lua_baselibopen(luaVM);
  lua_iolibopen(luaVM); 
  lua_strlibopen(luaVM); 
  lua_mathlibopen(luaVM); 
  
  // Используем lua.
    
  char* strLuaInput = "a = 1 + 1;\nprint( a);\n";

  lua_dostring(luaVM, strLuaInput);
 
  lua_close(luaVM);   

  return 0;
}

Выполнение кода теперь производит действительный результат:

Изображение

Я также могу вывести его более наглядно, изменяя команды, посланные lua:

#include <stdio.h>

extern "C"
{
 #include <lua.h>
} 

int main(int argc, char* argv[ ]) 
{ 
  lua_State* luaVM = lua_open(0);
  if (NULL == luaVM) 
  {
    printf("Error Initializing lua\n");
    return -1;
  } 

  // инициализация стандартных библиотечных функции lua
  lua_baselibopen(luaVM);
  lua_iolibopen(luaVM); 
  lua_strlibopen(luaVM); 
  lua_mathlibopen(luaVM); 
  
  // Используем lua.
    
 char* strLuaInput = "a = 1 + 1;\nprint( \"1 + 1: \" .. a);\n";
 
 lua_dostring(luaVM, strLuaInput);
 
 lua_close(luaVM);   
 
 return 0;
}

Проще говоря, результатом будет суммирование 1+1. Так, что я сделал - создал простой пример - эффективная иллюстрация использования скрипт-языка в вашем приложении. Исходник последнего примера может быть найден в предоставленном мной проекте SimpleInterpreter.

Это сравнительно простой материал и мы можем, основываясь на нем, построить простой интерпретатор. Все, что мы должны сделать сейчас - это добавить средства для захвата некоторого текста. Я сделал это в проекте FunctionalInterpreter. Это элементарный интерпретатор и не более чем простое расширение проекта SimpleInterpreter. Я не буду пробегаться по коду. Это просто расширение того, о чем я писал выше.

Страницы: 1 2 3 4 5 Следующая »

#Lua, #скрипты

17 августа 2003 (Обновление: 15 фев. 2012)

Комментарии [74]