[√]lua加载dll

简介: [√]lua加载dll

排查错误

error loading module 'xxx' from file 'xxxx.dll':

lua有自己的入口函数规则lua_open_模块名字,需要匹配,不能随便调整目录结构:

LUASOCKET_API int luaopen_socket_core(lua_State *L) {}
/* prefix for open functions in C libraries */
#define LUA_POF   "luaopen_"
#define POF   LUA_POF
static const char *mkfuncname (lua_State *L, const char *modname) {
  const char *funcname;
  const char *mark = strchr(modname, *LUA_IGMARK);
  if (mark) modname = mark + 1;
  funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
  funcname = lua_pushfstring(L, POF"%s", funcname);
  lua_remove(L, -2);  /* remove 'gsub' result */
  return funcname;
}

mkfuncname 是一个辅助函数,用于构建在 C 函数库中打开指定模块的函数名。它根据模块名生成 C 函数名,并将其格式化为 "luaopen_模块名" 的形式。在 Lua 调用 require 加载 C 函数库时,会调用这个生成的函数来进行初始化。这个函数使用 Lua 的字符串操作函数 luaL_gsub 将模块名中的 "." 替换为当前系统默认的函数名分隔符(通过 LUA_OFSEP 宏定义),然后调用 lua_pushfstring 将函数名压入 Lua 栈中。最后,通过 lua_remove 移除之前调用 luaL_gsub 生成的结果字符串。

一直报错找不到模块

image.png

原因是我的lua动态库名字不一致导致

image.png

可以看到core.dll依赖的是lua5.1.dll,如果随便将lua模块编译为lua.dll,可能就无法正确加载core.dll

要注意自己编译dll的时候,使用的lua版本,和宿主的lua版本必须一致,一般这种情况发生在分开编译dll和exe时比较容易发生。

lua dll demo

自己写的学习例子,一个最简单的lua dll:

#include <lua.h>           
#include <lauxlib.h>           
#include <stdio.h>
/**
 * 定义在lua中可调用的函数,要遵循规范:返回值必须为int,需传入lua_State
 */
static int test(lua_State *L);
int luaopen_dbg(lua_State *L);
#include "dbg.h"
static int test(lua_State *L)
{
    size_t len = 0;
    int num = luaL_checkinteger(L, 1);
    const char *str = luaL_checklstring(L, 2, &len);
    printf("come from test: num = %d  str = %s  len = %d\n", num, str, len);
    return 0;
}
int luaopen_dbg(lua_State *L)
{
    luaL_Reg l[] =
        {
            {"test", test},
            {NULL, NULL}};
    // luaL_newlib(L, l); // lua504才有这个函数
    luaL_register(L, "dbg", l);
    return 1;
}

定一个了一个dbg模块,在使用时将编译好的dbg.dll放在和lua.5.1.dll同目录,直接require,调用相关的函数即可

local lib = require(libName)
lib:test()

用法

dll的用法有点类似模块化开发,我们可以将不同的功能封装为一个模块,并编译为dll提供给别人使用,如果模块发生了更新,我只需要更新这个模块的dll就行了。

我还见过一种用法,你希望自己的应用软件仅仅是个壳,具体的实现放到了dll中,使用lua脚本调用dll,完成逻辑的执行,这种模式下的软件,其实dll非常有用,做WG的最喜欢这种方式。

在手游开发中,很少使用到这种技术,因为动态库有点水土不服。

目录
相关文章
|
数据格式 JSON 存储
Lua模块的加载与内存释放
今天早上听说一件事情让我觉得很诡异的事情:公司线上的一款游戏,加载一份配置资源后,内存涨了几十M,然后内存再也下不来了。因为好奇,所以要来了最大的一个配置文件(4.5M,去除空格与换行后的大小),进行测试。
2106 0
|
2月前
|
存储 NoSQL Redis
Redis的Lua脚本有什么作用?
Redis Lua脚本用于减少网络开销、实现原子操作及扩展指令集。它能合并操作降低网络延迟,保证原子性,替代不支持回滚的事务。通过脚本,代码复用率提高,且可自定义指令,如实现分布式锁,增强Redis功能和灵活性。
107 1
|
2月前
|
存储 NoSQL 关系型数据库
使用lua脚本操作redis
使用lua脚本操作redis
63 0
|
17天前
|
消息中间件 NoSQL Java
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
46 0
|
2月前
|
缓存 NoSQL Java
【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性
【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性
94 0
|
1月前
|
JSON 监控 数据格式
使用Lua代码扩展上网行为管理软件的脚本功能
本文介绍了如何使用Lua脚本增强上网行为管理,包括过滤URL、记录用户访问日志、控制带宽和自动提交监控数据到网站。Lua是一种轻量级语言,适合编写扩展脚本。文中提供多个示例代码,如URL过滤器、用户活动日志记录器和带宽控制器,帮助用户根据需求定制网络管理功能。通过这些示例,用户可以快速掌握Lua在上网行为管理中的应用。
114 4
|
16天前
|
NoSQL API Redis
使用Redis Lua脚本实现高级限流策略
使用Redis Lua脚本实现高级限流策略
33 0
|
17天前
|
消息中间件 NoSQL Java
Spring Boot中使用Redis和Lua脚本实现延时队列
Spring Boot中使用Redis和Lua脚本实现延时队列
|
19天前
|
NoSQL Java Redis
redis的lua脚本
在 Lua 脚本中,可以使用redis.call()函数来执行Redis命令.
16 0
|
2月前
|
算法 NoSQL Java
springboot整合redis及lua脚本实现接口限流
springboot整合redis及lua脚本实现接口限流
149 0