c调用lua

1.版本

1.1vs版本

vs2013

1.2lua版本

lua5.1,用luaForWindow安装

2.c调用lua

2.1编写lua代码

callLuaTest.lua

function add(a,b)
    return a+b;
end

function sub(a,b)
    return a-b;
end

然后把lua文件复制到项目目录下。

2.2复制头文件

vs创建控制台程序,在lua的安装目录下有个include文件夹,里面含有C API的相关头文件,我的路径为C:\Program Files (x86)\Lua\5.1\include,

在这里插入图片描述
将它们都复制到项目目录下,添加进工程里。
在这里插入图片描述

2.3添加lib库文件

在lua安装目录下有个lib文件夹,有这么些文件,

我们把lua5.1.lib或者lua51.lib复制到项目目录下,这里我选择用lua51.lib。
然后将lua51.lib添加到工程里,具体就是在项目上右击属性-》链接器-》输入-》附加依赖项。
在这里插入图片描述
最终我们的工程目录下应该是这样的:
在这里插入图片描述

2.4编写C++代码

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>
#include <stdio.h>
#include <string>
#include "lua.hpp"


float add(lua_State* L,float a, float b){
	//压入函数和参数
	lua_getglobal(L, "add"); //待调用的函数
	lua_pushnumber(L, a);//压入第一个参数
	lua_pushnumber(L, b);//压入第二个参数

	std::string strError;
	float fResult=0;
	//完成调用(2个参数,一个返回值)
	if (lua_pcall(L, 2, 1, 0) != 0)
	{
		luaL_error(L, "error running function 'f':%s", lua_tostring(L, -1));
	}

	//检索返回值
	if (!lua_isnumber(L, -1))
		luaL_error(L, "function 'f' must return a number");

	fResult = lua_tonumber(L, -1);

	//弹出返回值
	lua_pop(L, 1);

	return fResult;
}

float sub(lua_State* L, float a, float b){
	lua_getglobal(L, "sub");
	lua_pushnumber(L, a);
	lua_pushnumber(L, b);

	std::string strError;
	float fResult = 0;
	if (lua_pcall(L, 2, 1, 0) != 0)
	{
		luaL_error(L, "error running function 'f':%s", lua_tostring(L, -1));
	}

	if (!lua_isnumber(L, -1))
		luaL_error(L, "function 'f' must return a number");

	fResult = lua_tonumber(L, -1);
	lua_pop(L, 1);

	return fResult;
}



int _tmain(int argc, _TCHAR* argv[])
{
	lua_State* L = luaL_newstate();
	luaL_openlibs(L);

	luaL_dofile(L, "callLuaTest.lua");

	float fRes = add(L,1, 2);
	std::cout << "add result is " << fRes << std::endl;


	fRes = sub(L, 2, 1);
	std::cout << "sub result is " << fRes << std::endl;

	lua_close(L);

	system("pause");


	return 0;
}

编译一遍后,会生成Debug文件夹,里面会生成exe文件。
确认lua51.dll,lua5.1.dll的路径都添加环境变量PATH里面,让exe程序可以访问到,否则的话需要将这两个文件复制到Debug文件夹下,和exe文件处于同一下目录。因为我们使用的是lua51.lib,所以需要复制两个dll,假如使用的是lua5.1.lib,只需要复制lua5.1.dll就行了。两个lib的区别看这:
lua51.dll,lua51.lib 和 lua5.1.dll 和lua5.1.lib 的区别

运行程序后输出:
在这里插入图片描述

2.5代码分析

在调用lua_pcall时,第二个参数是传给待调用参数的参数数量,第三个参数是期望的结果数量,第四个参数是一个错误处理函数的索引。就像lua的赋值一样,lua_pcall会根据要求的数量来调整实际结果的数量,即压入nil或丢弃多余的结果。在压入结果前,lua_pcall会先删除栈中的函数及其参数。如果一个函数会返回多个结果,那么第一个结果最先压入。例如,函数返回了3个结果,第一个的索引就是-3,最后一个的索引是-1。
如果在lua_pcall的运行过程中有任何错误,lua_pcall会返回一个非零值,并在栈中压入一条错误信息。不过即便如此,它仍会弹出函数及其参数。在压入错误消息前,如果存在一个错误处理函数,lua_pcall就会先调用它。通过lua_pcall的最后一个参数指定这个错误处理函数。零表示没有错误处理函数,那么最终的错误消息就是原来的消息。若传入非零参数,那么这个参数就应该是一个错误处理函数在栈中的索引。因此错误处理函数必须先压入栈中,也就是必须位于待调用函数及其参数的下面。

具体内容可以看《lua程序设计(第2版)》第25章的内容。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值