Table of Contents

Lua加载动态链接库

返回:Lua和C协作


C++

#pragma once
 
// DLL工程里面还是要先配置好Lua环境
extern "C" {
#include "LuaSource/lua.h"
#include "LuaSource/lualib.h"
#include "LuaSource/lauxlib.h"
}
 
// 导出函数
#define CPP_FOR_LUA_API __declspec(dllexport)
 
// 这个函数的名称根据库的名称进行修改,比如这个工程名是:CppForLua
// Lua端require的时候会调用
extern "C" CPP_FOR_LUA_API int luaopen_CppForLua(lua_State* L);
#include "Export.h"
 
#include <cstdio>
 
// 参数和返回值的处理方式还是和平常一样
static int libLibInfo(lua_State* L)
{
    puts("C++ Dll Lib, Version 1.0");
    return 0;
}
 
static int libAdd(lua_State* L)
{
    int x = (int)lua_tonumber(L, -2);
    int y = (int)lua_tonumber(L, -1);
    int r = x - y;
    lua_pushnumber(L, r);
    return 1;
}
 
static int libSub(lua_State* L)
{
    int x = (int)lua_tonumber(L, -2);
    int y = (int)lua_tonumber(L, -1);
    int r = x + y;
    lua_pushnumber(L, r);
    return 1;
}
 
// 定义一个导出库包含的内容,最后必须以NULL结尾
static const luaL_Reg libContent[] =
{
    {"Add", libAdd},
    {"Sub", libSub},
    {NULL, NULL}
};
 
int luaopen_CppForLua(lua_State* L)
{
    // 这些函数都注册到了全局
    lua_register(L, "GlobalLibInfo", libLibInfo);
 
    lua_register(L, "GlobalAdd", libAdd);
    lua_register(L, "GlobalSub", libSub);
 
    // 不能像下面这么写
    // lua_register(L, "LibMath.Add", libAdd);
    // lua_register(L, "LibMath.Sub", libSub);
 
    // 创建一个Lib,Lib里面的内容不是注册到全局的
    luaL_newlib(L, libContent);
 
    return 1; // 创建了1个Lib:向栈里压入了1个内容
}

Lua

local CppForLua = require 'CppForLua' -- 导入DLL
 
-- 导入DLL的时候,注册的全局函数可以直接使用
GlobalLibInfo()
print(GlobalAdd(5,4))
print(GlobalSub(5,4))
 
-- Lib中的内容放在了CppForLua里面,通过CppForLua调用
print(CppForLua.Add(5,4))
print(CppForLua.Sub(5,4))

Output

C++ Dll Lib, Version 1.0
1.0
9.0
1.0
9.0