Большой Воронежский Форум
» Программирование>Встраивание LUA в C# и C++
Delphi7 18:03 21.12.2007
LUA - один из самых лучших современных встраиваемых языков программирования. Интересует технология его встраивания в программы(Win32), написанные на C# или С++. Один из способов есть на ilovelua.narod.ru, но следование инструкциям не приводит к желаемому результату. Если кто этим занимался, поделитесь пожалуйста опытом. [Ответ]
DeniSS1 18:35 21.12.2007
Delphi7, а что за язык? [Ответ]
Pengvin 18:55 21.12.2007
для C# http://luaforge.net/projects/luainterface/
в С++ по моему вполне приемлимый способ встраивания lua.h, те стандартный. [Ответ]
Pengvin 19:08 21.12.2007
Покапался в своих поделках вот код для С++.

Сообщение от :
/ lua_sample.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string.h>
extern "C"
{
#include <lua.hpp>

static void callalert (lua_State *L, int status) {
if (status != 0) {
lua_getglobal(L, "_ALERT");
if (lua_isfunction(L, -1)) {
lua_insert(L, -2);
lua_call(L, 1, 0);
}
else { /* no _ALERT function; print it on stderr */
fprintf(stderr, "%s\n", lua_tostring(L, -2));
lua_pop(L, 2); /* remove error message and _ALERT */
}
}
}


static int aux_do (lua_State *L, int status) {
if (status == 0)
{ /* parse OK? */
status = lua_pcall(L, 0, LUA_MULTRET, 0); /* call main */
}
callalert(L, status);
return status;
}

LUALIB_API int lua_dofile (lua_State *L, const char *filename) {
return aux_do(L, luaL_loadfile(L, filename));
}


LUALIB_API int lua_dobuffer (lua_State *L, const char *buff, size_t size,
const char *name) {
return aux_do(L, luaL_loadbuffer(L, buff, size, name));
}
LUALIB_API int lua_dostring (lua_State *L, const char *str) {
return lua_dobuffer(L, str, strlen(str), str); }

}

int script_Print( lua_State* L)
{
printf("SCRIPT:");
int i;
int n = lua_gettop(L); /* number of arguments */
for (i=1;i<=n;i++) printf(lua_tostring(L,i));
printf("\n");
lua_pushnumber(L,0);
return 1;
}

int flag=0;

int script_GetFlag(lua_State* L)
{
lua_pushnumber(L,flag);
return 1;
}

int script_SetFlag(lua_State* L)
{
if (lua_isnumber(L,-1))
{
flag=(int)lua_tointeger(L, -1);
printf("%d",flag);
}
else
{
lua_pushstring(L, "incorrect argument to function \"setflag\" ");
lua_error(L);
}
return 0;

}


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

lua_register(luaVM,"print",script_Print);
lua_register(luaVM,"getflag",script_GetFlag);
lua_register(luaVM,"setflag",script_SetFlag);

//luaL_loadstring(luaVM,strLuaInput);
//int errcode = lua_pcall(luaVM,0,0,0);
//int errcode = lua_dostring(luaVM,strLuaInput);
int errcode=lua_dofile(luaVM,"E:/lua.lub");
if (errcode == LUA_ERRMEM)
{
printf("Memmory error\n");
}
if (errcode==LUA_ERRRUN)
{
printf("Run time error\n");
}
if (errcode==LUA_ERRERR)
{
printf("Calling error\n");
}

lua_close(luaVM);

printf("Press any key");
char* s="hren";
scanf_s(s);
return 0;
}

[Ответ]
Pengvin 19:14 21.12.2007
для С# c использование упомянутого LuaInterface

Сообщение от :
using System;
using System.Reflection;
using System.Collections;
using System.Text;
using System.ComponentModel;
using LuaInterface;
using CSharpLua.Structs;

namespace ConsoleApplication1
{
class Program
{
static Lua pLuaVM = null;
bool bRunning = true;
static Hashtable pLuaFuncs = null;
static Hashtable pLuaPackages = null;

public Program()
{
pLuaVM = new Lua();
pLuaFuncs = new Hashtable();
pLuaPackages = new Hashtable();
registerLuaFunctions(null, this, null);
Console.WriteLine("CSharp Lua Console v0.1");
}

public static void registerLuaFunctions(String strPackage, Object pTarget, String strPkgDoc)
{
if (pLuaVM == null || pLuaFuncs == null || pLuaPackages == null)
return;

LuaPackageDescriptor pPkg = null;

if (strPackage != null)
{
pLuaVM.DoString(strPackage + " = {}");
pPkg = new LuaPackageDescriptor(strPackage, strPkgDoc);
}

Type pTrgType = pTarget.GetType();

foreach (MethodInfo mInfo in pTrgType.GetMethods())
{
foreach (Attribute attr in Attribute.GetCustomAttributes(mInfo))
{
if (attr.GetType() == typeof(AttrLuaFunc))
{
AttrLuaFunc pAttr = (AttrLuaFunc)attr;
ArrayList pParams = new ArrayList();
ArrayList pParamDocs = new ArrayList();
String strFName = pAttr.getFuncName();
String strFDoc = pAttr.getFuncDoc();
String[] pPrmDocs = pAttr.getFuncParams();
ParameterInfo[] pPrmInfo = mInfo.GetParameters();
if (pPrmDocs != null && (pPrmInfo.Length != pPrmDocs.Length))
{
Console.WriteLine("Function " + mInfo.Name + " (exported as " + strFName + ") argument number mismatch. Declared " + pPrmDocs.Length + " but requires " + pPrmInfo.Length + ".");
break;
}

for (int i = 0; i < pPrmInfo.Length; i++)
{
pParams.Add(pPrmInfo[i].Name);
pParamDocs.Add(pPrmDocs[i]);
}

LuaFuncDescriptor pDesc = new LuaFuncDescriptor(strFName, strFDoc, pParams, pParamDocs);
if (pPkg != null)
{
pPkg.AddFunc(pDesc);
pLuaVM.RegisterFunction(strPackage + strFName, pTarget, mInfo);
pLuaVM.DoString(strPackage + "." + strFName + " = " + strPackage + strFName);
pLuaVM.DoString(strPackage + strFName + " = nil");
}
else
{
pLuaFuncs.Add(strFName, pDesc);
pLuaVM.RegisterFunction(strFName, pTarget, mInfo);
}
}
}
}

if (pPkg != null)
pLuaPackages.Add(strPackage, pPkg);
}

[AttrLuaFunc("quit", "Exit the program.")]
public void quit()
{
bRunning = false;
}

[AttrLuaFunc("runscript", "Runs scriptfile", "Command / Package to get help of.")]
public void runscript(string fname)
{
pLuaVM.DoFile(fname);
}

[AttrLuaFunc("echo", "Show help for a given command or package", "Command / Package to get help of.")]
public string echo(string echo1)
{
Console.WriteLine("echo:" + echo1);
return echo1;
}


[AttrLuaFunc("helpcmd", "Show help for a given command or package", "Command / Package to get help of.")]
public void help(String strCmd)
{
if (pLuaFuncs.ContainsKey(strCmd))
{
LuaFuncDescriptor pDesc = (LuaFuncDescriptor)pLuaFuncs[strCmd];
Console.WriteLine(pDesc.getFuncFullDoc());
return;
}

if (strCmd.IndexOf(".") == -1)
{
if (pLuaPackages.ContainsKey(strCmd))
{
LuaPackageDescriptor pDesc = (LuaPackageDescriptor)pLuaPackages[strCmd];
pDesc.WriteHelp();
return;
}
else
{
Console.WriteLine("No such function or package: " + strCmd);
return;
}
}

String[] strParts = strCmd.Split('.');

if (!pLuaPackages.ContainsKey(strParts[0]))
{
Console.WriteLine("No such function or package: " + strCmd);
return;
}

LuaPackageDescriptor pPkgDesc = (LuaPackageDescriptor)pLuaPackages[strParts[0]];

if (!pPkgDesc.HasFunc(strParts[1]))
{
Console.WriteLine("Package " + strParts[0] + " doesn't have a " + strParts[1] + " function.");
return;
}

pPkgDesc.WriteHelp(strParts[1]);
}

[AttrLuaFunc("help", "List available commands.")]
public void help()
{
Console.WriteLine("Available commands: ");
Console.WriteLine();

IDictionaryEnumerator Funcs = pLuaFuncs.GetEnumerator();
while (Funcs.MoveNext())
{
Console.WriteLine(((LuaFuncDescriptor)Funcs.Value) .getFuncHeader());
}

if (pLuaPackages.Count > 0)
{
Console.WriteLine();
Console.WriteLine("Available packages: ");

IDictionaryEnumerator Pkgs = pLuaPackages.GetEnumerator();
while (Pkgs.MoveNext())
{
Console.WriteLine((String)Pkgs.Key);
}
}
}

public void run()
{
String strBuffer = "";
Boolean bInBlock = false;

while (bRunning)
{
if (!bInBlock)
Console.Write("> ");
else
Console.Write(": ");

String strConsoleIn = Console.ReadLine();
if (!bInBlock && strConsoleIn == "beginblock")
{
bInBlock = true;
}
else if (bInBlock && strConsoleIn == "breakblock")
{
bInBlock = false;
strBuffer = "";
Console.WriteLine();
}
else if (bInBlock && strConsoleIn == "endblock")
{
bInBlock = false;
try
{
Console.WriteLine();
pLuaVM.DoString(strBuffer);
Console.WriteLine();
}

catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
Console.WriteLine();
}

finally
{
strBuffer = "";
}
}
else if (bInBlock)
{
strBuffer += strConsoleIn + "\n";
}
else
{
try
{
Console.WriteLine();
pLuaVM.DoString(strConsoleIn);
Console.WriteLine();
}

catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
Console.WriteLine();
}
}
}
}

static void Main(string[] args)
{
Program pMain = new Program();
pMain.run();
}
}
}

[Ответ]
The_God 22:36 21.12.2007
афигеть телега, а файлики с кодом прилепить никак нельзя ? я например без раскраски и без отступов вабще в коде не ориентируюсь [Ответ]
Pengvin 23:24 21.12.2007
Ну ладно выложу проекты. Код писался для lua 5.1.
Изображения
[Ответ]
The_God 23:54 21.12.2007
прописал пути к луа, скомпилил

написал файлик тестовый lua.lua:
print( 1, " hello ", "lamer" )
print( getflag() )

результат на экране:
SCRIPT:1 hello lamer
SCRIPT:0
Press any key

Сообщение от Delphi7:
не приводит к желаемому результату

и не понял че не так, он должен был винт отформатировать чтоли ?

ps зырил c++ [Ответ]
Delphi7 11:35 22.12.2007
Спасибо всем огромное, вечером буду разбираться! О результатах напишу отдельно. [Ответ]
Delphi7 23:55 25.12.2007

Сообщение от The_God:
прописал пути к луа, скомпилил

нельзя ли здесь подробнее?
Если Вам не трудно, я бы очень рад был, если будет как мона более подробнее......... [Ответ]
Yandex 18:07 28.12.2007
Для C++
1. Скачать lua с www.lua.org
2. Собрать lua.lib из изходников
3. В самом проекте подключить lua.h
4. В коде проекта

Сообщение от :
#include<lua.h>
...
lua_State* g_Lua;
...
g_Lua = lua_open();
if (NULL == g_Lua)
{
sgeLog ("Init LUA failed...\n");
return -1;
}
luaL_openlibs(g_Lua);

Потом лучше заботать, что такое враппер и заиспользовать tolua++ или luabind. Дальше можно по манам делать.

Если не в моготу самому собирать, то можешь скачать мой проектик с использованием Lua - http://sgeproject.narod.ru/sge_0.9.zip.
Это простенький движок для Win/WinCE платформ с Lua в качестве native языка. [Ответ]
Вверх