设为首页 加入收藏

TOP

Lua与C/C++交互――C/C++导出Dll(一)
2014-11-24 12:43:45 】 浏览:398
Tags:Lua C/C 交互 导出 Dll

0.简介

Lua(念“鲁啊”)作为一门发展成熟的脚本语言,正在变得越来越流行。它也可以作为和C/C++执行脚本交互的语言。并且Lua的整个库很小,我安装了最新的正式版Lua 5.1版本,而整个静态链接的lua.dll才164KB,所以Lua很轻量,特别适合轻量级脚本嵌入。

看文章名就知道,我们要讲Lua和C/C++的交互,这期讲Lua如何使用C/C++的东西——Lua通过C/C++导出的dll来调用。OK,Let’s Go!首先,你得去Lua官网http://www.lua.org获取最新版本的Lua。

1.准备工作

安装完Lua,需要在Visual Studio中配置Lua路径,使得你的编译器能搜寻到。关于VS2010的配置,见我的博文《VS2010 C++目录配置》一文。完成后新建一个Dll工程便可以了。

我们用一个在Lua中显示Windows对话框的程序来简要介绍一下,程序虽小,但五脏俱全。程序如下:

//

// 将一些有用的Win32特性导出.

// 以便在Lua中使用.

//

extern "C"

{

#include

#include

#include

#pragma comment(lib, "lua.lib")

};

#include

#include

using namespace std;

static const char* const ERROR_ARGUMENT_COUNT = "参数数目错误!";

static const char* const ERROR_ARGUMENT_TYPE = "参数类型错误!";

//

// 发生错误,报告错误.

//

void ErrorMsg(lua_State* luaEnv, const char* const pszErrorInfo)

{

lua_pushstring(luaEnv, pszErrorInfo);

lua_error(luaEnv);

}

//

// 检测函数调用参数个数是否正常.

//

void CheckParamCount(lua_State* luaEnv, int paramCount)

{

// lua_gettop获取栈中元素个数.

if (lua_gettop(luaEnv) != paramCount)

{

ErrorMsg(luaEnv, ERROR_ARGUMENT_COUNT);

}

}

//

// 显示Windows对话框.

// @param [in] pszMessage string 1

// @param [in] pszCaption string 2

//

extern "C" int ShowMsgBox(lua_State* luaEnv)

{

const char* pszMessage = 0;

const char* pszCaption = 0;

// 检测参数个数是否正确.

CheckParamCount(luaEnv, 2);

// 提取参数.

pszMessage = luaL_checkstring(luaEnv, 1);

pszCaption = luaL_checkstring(luaEnv, 2);

if (pszCaption && pszMessage)

{

::MessageBox(

NULL,

pszMessage,

pszCaption,

MB_OK | MB_ICONINFORMATION

);

}

else

{

ErrorMsg(luaEnv, ERROR_ARGUMENT_TYPE);

}

// 返回值个数为0个.

return 0;

}

//

// 导出函数列表.

//

static luaL_Reg luaLibs[] =

{

{"ShowMsgBox", ShowMsgBox},

{NULL, NULL}

};

//

// Dll入口函数,Lua调用此Dll的入口函数.

//

extern "C" __declspec(dllexport)

int luaopen_WinFeature(lua_State* luaEnv)

{

const char* const LIBRARY_NAME = "WinFeature";

luaL_register(luaEnv, LIBRARY_NAME, luaLibs);

return 1;

}

//:-)

2.程序解析

首先我们包含Lua的头文件,并链入库文件。注意:Lua的头文件为C风格,所以用external “C”来含入。在此例中,我们最终的导出函数为“ShowMsgBox”。

每一个导出函数的格式都为:

extern “C”int Export_Proc_Name(luaState* luaEnv);

其中,luaState*所指的结构中包含了Lua调用此Dll时必备的Lua环境。那么Lua向函数传递参数该怎么办呢?实际上是用luaL_check[type]函数来完成的。如下:

const char* pHelloStr = luaL_checkstring(luaEnv, 1);

double value = luaL_checknumber(luaEnv, 2);

int ivalue = luaL_checkint(luaEnv, 3);

luaL_check系列函数的第二个参数是Lua调用该函数时传递参数从坐到右的顺序(从1开始)。

然后我们看到,static的一个luaL_Reg的结构数组中包含了所有要导出的函数列表。最后通过luaopen_YourDllName的一个导出函数来完成一系列操作。YourDllName就是你最终的Dll的名字(不含扩展名)。因为你在Lua中调用此Dll时,Lua会根据此Dll名字找luaopen_YourDllName对应的函数,然后从此函数加载该Dll。

Dll入口函数格式如下:

extern "C" __declspec(dllexport)

int luaopen_WinFeature(lua_State* luaEnv)

{

const char* const LIBRARY_NAME = "WinFeature";

luaL_register(luaEnv, LIBRARY_NAME, luaLibs);

return 1;

}

我们通过luaL_register将LIBRARY_NAME对应的库名,以及luaL_Reg数组对应的导出列表来注册到lua_State*对应的Lua环境中。

3.Lua调用

那么我

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇C++ Primer 第三章 标准库类型 笔.. 下一篇poj 2456 二分法 最大化最小值

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目