lua学习(五)

来源:互联网 发布:遗传优化算法 编辑:程序博客网 时间:2024/04/28 05:48

上周看了一下lua的package和OO,感觉不错, lua并不像python程序员抨击的那样不优美.

顺便看了一下pil中,  c函数调用lua以及lua调用c函数的内容.
一、c调用lua函数一般的过程是:
1. load一个lua的文件,形成一个闭包并执行它
2. 在栈中压入函数的名称
3. 依次在栈中压入函数的实参
4. 使用lua_pcall调用lua函数。 形式是: lua_pcall(L, 参数个数,结果个数, 错误处理函数在栈中的索引)
    此时此函数相关的栈已经被清空。执行lua完毕后,如果成功,结果依次将压入栈中, 如果不成功,错误信息将 压入栈中
5. 从栈中读取返回结果或者错误信息。
下面是一则实例:
--[[
    func.lua
--]]
function f(x, y)
 return (x^2 * math.sin(y))/(1 - x)
end

/**
 *  main.cpp
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

void error (lua_State *L, const char *fmt, ...)
{
 va_list argp;
 va_start(argp, fmt);
 vfprintf(stderr, fmt, argp);
 va_end(argp);
 lua_close(L);
 exit(EXIT_FAILURE);
}

int main (void)
{

 lua_State *L = luaL_newstate();

 lua_cpcall(L, luaopen_base, 0);
 lua_cpcall(L, luaopen_io, 0);
 lua_cpcall(L, luaopen_math, 0);
 lua_cpcall(L, luaopen_string, 0);


 // 载入func.lua,并运行
 if (luaL_loadfile(L, "func.lua") || lua_pcall(L, 0, 0, 0))
  error(L, "cannot run configuration file: %s", lua_tostring(L, -1));

 double x, y;

 printf("请输入一个数字:");
 scanf("%d", &x);
 printf("%d/n", x);

 printf("再输入一个数字:");
 scanf("%d", &y);
 printf("%d/n", y);

 lua_getglobal(L, "f");
 lua_pushnumber(L, x);
 lua_pushnumber(L, y);
 if (lua_pcall(L, 2, 1, 0) != 0)
  error(L, "error running function `f': %s", lua_tostring(L, -1));

 if (!lua_isnumber(L, -1))
  error(L, "function `f' must return a number");
 double z = lua_tonumber(L, -1);
 lua_pop(L, 1); /* pop returned value */


 printf("结果是: /t %d' /n", z);

 lua_close(L);
}

二、lua调用c函数(写成库的例子)
lua调用库在windows下是dll文件,在unix/linux下面是so文件
vs的过程如下:
1. 新建一个dll的工程
2. 定义一个def文件,定义dll的导出,我的mylib.def定义如下:
LIBRARY  mylib.dll
DESCRIPTION "aol's first dll for lua"
EXPORTS
luaopen_mylib
3. 编写库,新建一个cpp文件.
4. 定义库函数,这里以pil的lsin函数,输出传入参数的sin()值
5. 定义luaL_reg数组,这个是注册一系列公开给lua调用的函数数组. 数组最后一个元素必须是 {NULL, NULL} 的luaL_reg结构用来做结束标识.
6. 用luaL_openlib声明主函数
实例如下:
/*
 * main.cpp
 */
#include <math.h>

extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

static int l_sin (lua_State *L)
{
 double d = luaL_checknumber(L, 1);
 lua_pushnumber(L, sin(d));
 return 1; /* number of results */
}

static const struct luaL_reg mylib [] = {
 {"lsin", l_sin},
 {NULL, NULL} /* sentinel */
};

int luaopen_mylib (lua_State *L)
{
 luaL_openlib(L, "mylib", mylib, 0);
 return 1;
}
生成mylib.dll之后把文件拷入lua的安装根目录就可以调用了.
运行lua,进入lua环境,调用如下(lua版本5.1):
> package.loadlib("mylib.dll", "luaopen_mylib")()
> print(mylib.lsin(10))
-0.54402111088937
>


原创粉丝点击