lua调用C/C++的函数,十分钟快速掌握

系列文章目录


lua调用C\C++动态库函数


摘要

在现代软件开发中,Lua作为一种轻量级脚本语言,在游戏开发、嵌入式系统等领域广泛应用。Lua与C/C++的高度集成使得开发者能够借助其灵活性和高效性实现更强大的功能。本文将通过一些简单、直接的示例探讨Lua调用C/C++函数的技术。Lua通过调用C/C++实现的extern "C"函数来交互,首先,我们需要在C/C++中编写适当的包装函数,并使用Lua API将其注册到Lua虚拟机中,这一过程包括参数的传递、函数调用以及返回值的处理。通过合理设计的接口,生成动态库文件使其在lua脚本中用require引用,我们能够在Lua中直接调用C/C++函数,实现跨语言的功能扩展。这为项目提供了更大的灵活性,允许开发者在Lua中编写高层逻辑,同时利用C/C++的性能优势处理底层任务。从实践角度看,Lua调用C/C++的技术架构在提高代码可维护性和性能的同时,也为项目带来了更强大的扩展性。通过深入学习Lua与C/C++交互的原理和最佳实践,开发者可以更好地应用这一技术,提升项目的开发效率和整体性能。

还有一种提供C API给lua用的方法:把lua的源码clone一份自己改,定义一个library导出,然后编译成可执行文件或者库,那么lua依然可以通过require引入和使用。


提示:以下是本篇文章正文内容,下面案例可供参考

环境

软件 版本
Windows 10
visual studio 2022
lua 5.1
C++ 17

使用步骤

你需要有个lua环境

在lua官网下载编译好的动态库、静态库、头文件和可执行二进制文件。

https://luabinaries.sourceforge.net/

拿到lua.hpp头文件和lua5.1.lib静态库,加到自己项目的引用。

引入库

lua.hpp头文件去安装目录找。

码代码

头文件

代码如下(示例):

cpp 复制代码
#pragma once
/*
几个简单的函数
*/

// step 1
#include "lua.hpp"

// step 2 定义自己的函数
int addTwoNumber(int a, int b)
{
	return a + b;
}

const char* linkNameAndNumber(const char* name, int age)
{

	std::unique_ptr<char> pbuf(new char[128]);
	sprintf(pbuf.get(), "Your name is %s, and %d years old.", name, age);
	std::string r(pbuf.get());

	std::cout<<"C source output " << r << std::endl;

	auto rbuf = new char[128];
	memcpy(rbuf, pbuf.get(), sizeof(pbuf.get()));
	std::cout << rbuf << " buffer content" << std::endl;
	return rbuf;
}

const wchar_t* wLinkNameAndNumber(const wchar_t* name, int age)
{

	std::unique_ptr<wchar_t> pbuf(new wchar_t[128]);
	wsprintf(pbuf.get(), L"Your name is %s, and %d years old.", name, age);
	std::wstring r(pbuf.get());

	std::wcout << L"C source output " << r << std::endl;
	return r.c_str();
}

/**
 * step 3 定义函数的wrapper
 * \brief origin function
 * \param L
 * \return
 */
extern "C" int addTwoNumberWrapper(lua_State * L)
{
	double a, b, sum = 0;
	int pCount = lua_gettop(L);
	for (int i = 0; i <= pCount; ++i)
	{
		if (i == 1)
		{
			a = lua_tonumber(L, i);
		}
		else if (i == 2)
		{
			b = lua_tonumber(L, i);

		}
	}

	sum = addTwoNumber(a, b);
	lua_pushnumber(L, sum);

	return 1;
}

extern "C" int linkNameAndNumberWrapper(lua_State * L)
{
	int pCount = lua_gettop(L);
	const char* name = lua_tostring(L, 1);
	int age = lua_tointeger(L, 2);

	auto result = linkNameAndNumber(name, age);
	lua_pushstring(L, result);
	
	return 1;
}

dllmain.cpp

cpp 复制代码
/**
 * step 4 定义函数的wrapper注册表
 * \brief function registry table
 */
static luaL_Reg cMethods[] = {
	{"addTwoNumber", addTwoNumberWrapper},
	{"linkNameAndNumber", linkNameAndNumberWrapper},
	{NULL, NULL}
};


/*
 step 5 创建lua_openlibrary函数
*/
extern "C" __declspec(dllexport)
int luaopen_MyMethodLib(lua_State * L)
{
	std::cout << "=========载入MyMethodLib库======" << std::endl;
	const char* libName = "MyMethodLib";
	luaL_register(L, libName, cMethods);
	return 1;
}

Windows平台生成的动态库可以使用visual studio命令行工具的dumpbin /exports 查看导出符号表,检查函数导出情况。

生成的动态库放到lua安装目录下或者自己的lua脚本目录下。

lua代码

lua 复制代码
local myMethodLib = require("MyMethodLib")

local r1 = myMethodLib.addTwoNumber(1,2)
local r2 = myMethodLib.linkNameAndNumber("Michael",67)

print(r1, r2)

使用lua.exe运行脚本即可。

相关推荐
逻各斯8 分钟前
redis中的Lua脚本,redis的事务机制
java·redis·lua
cookies_s_s1 小时前
Linux--进程(进程虚拟地址空间、页表、进程控制、实现简易shell)
linux·运维·服务器·数据结构·c++·算法·哈希算法
不想编程小谭2 小时前
力扣LeetCode: 2506 统计相似字符串对的数目
c++·算法·leetcode
曼巴UE53 小时前
UE5.3 C++ TArray系列(一)
开发语言·c++·ue5
阿巴~阿巴~3 小时前
多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题
开发语言·数据结构·c++·算法·宽度优先
CoderCodingNo4 小时前
【GESP】C++二级真题 luogu-b3924, [GESP202312 二级] 小杨的H字矩阵
java·c++·矩阵
waicsdn_haha4 小时前
Visual Studio Code 2025 安装与高效配置教程
c语言·ide·windows·vscode·微软·编辑器·win7
刃神太酷啦5 小时前
堆和priority_queue
数据结构·c++·蓝桥杯c++组
Heris995 小时前
2.22 c++练习【operator运算符重载、封装消息队列、封装信号灯集】
开发语言·c++
----云烟----5 小时前
C/C++ 中 volatile 关键字详解
c语言·开发语言·c++