lua加载dll文件套路

#Lua:Lua调用C++生成的DLL库 时间 2022-09-24 20:16:00原文主题。 阅读详情

在做游戏的时候,经常会要使用dll来封装库给lua来使用。本文将用于说明如何来通过lua来加载dll。

lua加载代码

在loadlib.c文件中的127lines


static void *ll_load (lua_State *L, const char *path) {
  HINSTANCE lib = LoadLibraryA(path);
  if (lib == NULL) pusherror(L);
  return lib;
}


static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
  lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym);
  if (f == NULL) pusherror(L);
  return f;
}

当加载dll文件的时候,分为两步来走:

加载dll文件

首先通过预定的package.cpath搜索目录来查找dll文件是否存在。
这里是一个指定加载目录的实例

package.cpath = package.cpath .. ';c:/my_lua_dll_lib/?dll;'

找到lua的入口函数

通过GetProcAddress到你的dll文件中查找入口函数。这个函数名是一个固定的:
loadlib.c文件中能读到这个代码:

/* prefix for open functions in C libraries */
#define LUA_POF     "luaopen_"

#define POF     LUA_POF

static int loader_C (lua_State *L) {
  const char *funcname;
  const char *name = luaL_checkstring(L, 1);
  const char *filename = findfile(L, name, "cpath");
  if (filename == NULL) return 1;  /* library not found in this path */
  funcname = mkfuncname(L, name);
  if (ll_loadfunc(L, filename, funcname) != 0)
    loaderror(L, filename);
  return 1;  /* library loaded successfully */
}

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;
}

输入的参数只有”your_dll_name”,在mkfuncname函数将会拼接函数。

dll编写

导出的细节

lua是一个默认为c语言的引擎,在使用vs来编写dll的时候,默认创建源文件的时候将会为cpp文件。所以这个里面写的function的时候,默认是使用的c++的语法。当被导出的时候我们可以通过depends工具来分析dll中的function:
这里写图片描述

如果代码是C和C++混编的时候,注意这个点。如果函数是在cpp中编写的那就需要在函数开始的地方加上:

extern "C"

实例

参考

//#include "stdio.h"
#include "windows.h"
#ifdef _cplusplus  
extern "C"{
#endif
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

extern  int  isquare(lua_State *L);
extern  int  alert(lua_State *L);
#ifdef _cplusplus
}
#endif

int luaopen_add(lua_State *L){
    lua_register(
            L,               /* Lua 状态机 */
            "square",        /*Lua中的函数名 */
            isquare          /*当前文件中的函数名 */
            );  
   lua_register(L,"alert",alert);
//    lua_register(L,"cube",icube);
    return 0;
}


int alert(lua_State *L)
{
    const char * desc = lua_tostring(L,-1);
    MessageBox(NULL,desc,"alert",MB_OK);
    return 1;
}

int isquare(lua_State *L){              /* C中的函数名 */
    float rtrn = lua_tonumber(L, -1);      /* 从Lua虚拟机里取出一个变量,这个变量是number类型的 */
    //printf("Top of square(), nbr=%f\n",rtrn);
    lua_pushnumber(L,rtrn*rtrn);           /* 将返回值压回Lua虚拟机的栈中 */
    return 1;                              /* 这个返回值告诉lua虚拟机,我们往栈里放入了多少个返回值 */
}

C加载函数实验

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

#include "stdafx.h"
#include <string>
#include <iostream>
#include <sstream>

#include <lua.hpp>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

typedef int(*lua_CFunction) (lua_State *L);

int main(int argn, char *argv[])
{
    if (argn != 2)
    {
        return -100;
    }

    std::string dll = argv[1];
    std::stringstream ss;
    ss << "xxxxxxxxxxxxxxxxxxxxx" << dll << ".dll";
    std::string dll_name = ss.str();
    HINSTANCE lib = ::LoadLibraryA(dll_name.c_str());
    if (lib == NULL) {
        std::cerr << "LoadLibraryA failed, errorcode: " << ::GetLastError() << std::endl;
        return -1;
    }

    ss.str("");
    ss << "luaopen_" << dll;
    std::string sym = ss.str();
    lua_CFunction f = (lua_CFunction)::GetProcAddress((HINSTANCE)lib, sym.c_str());
    if (f == NULL)
    {
        std::cerr << "GetProcAddress failed: " << ::GetLastError() << std::endl;
    }
    return 0;
}

Unity手游热更实战:Lua+XLua框架搭建与避坑指南 热更新是手游绕不开的刚需,尤其在应用商店审核周期长、紧急Bug无法快速发版的场景下,逻辑热更成为唯一止血通道。脚本语言Lua凭借轻量、解释执行、天然免疫IL2CPP裁剪等特性,成为Unity项目中最成熟的热更载体,而XLua作为维护活跃的插件,提供了高效的C#与Lua交互能力和灵活的Hotfix机制。掌握Lua与XLua的原理与工程实践,能显著缩短线上问题定位时间,并降低包体体积和崩溃风险。从UI事件绑定、网络消息回调到资源热更清单管理,一套设计清晰的热更框架能帮助团队应对版本迭代挑战。本文从环境接入、模块 阅读详情

相关推荐

Unity小游戏热更新实战:HybridCLR+YooAsset改造复盘

热更新是手游持续运营的核心能力,但在微信小游戏等平台,传统App热更方案会遭遇程序集加载受限、文件系统隔离和包体限制等新关卡。HybridCLR通过在IL2CPP层引入解释执行模式,让C#业务逻辑无需重写即可实现代码热更;YooAsset则提供完整的资源版本管理和增量下载能力,并适配WebGL的IDBFS存储。二者配合,可将代码与资源统一纳入一条更新管线,实现轻量启动和按需加载。该方案特别适合需要高频更新玩法的中轻度Unity小游戏,帮助团队在合规前提下高效迭代。本文复盘了工程改造、构建流程与平台适配中的关

weixin_31497453的博客 260

Lua设置搜索路径package.path和package.cpath

--方法1 只加载想要的目录 package.path = "../myLuaTest/myLuaCode/?.lua;" --方法2 增加目录 package.path = "../myLuaTest/myLuaCode/?.lua;"..package.path print(package.path); --搜索指定路径下,以.so结尾的文件 package.cpath = "../y...

燃尽的博客 2万+

Lua加载Dll库来扩展功能

网上找到的LUA与C的互动程序很多,但Delphi的很少。写LUA导入Dll库的,没找到。自己从C代码中扒出一点,只能用一点点功能。抛砖引玉吧。大师们发个全一点的代码吧。邮箱:shb_a@126.com 文件目录: lua53.dll LUA自带的 lualib.dll 自测试用的,仅有三个函数:lua_sleep-延时,showm-返回文本,lua_moveto-返回2个数值 太多的东西,没弄明白。 LuaTest.exe 非常简单的LUA执行程序,代替黑窗口_a testlua.lua 不解释了 说明.txt 本文件 lualib 目录 lualib.dll delphi7源代码。高手你发挥的时候到了……

package.path和package.cpath

如果是一个 *.LUA 的文件, 里面用到了自己写的库, 或者第三方写的库, 但是你不想把它放到 lua 的安装目录里, 则在代码里面可以指定require搜索的路径。     package.path = '/usr/local/share/lua/5.1/?.lua;/home/resty/?.lua;'    --搜索lua模块     package.cpath = '

蚂蚁的坚持 7946

梦幻西游服务端加PC端自带源代码

梦幻西游服务端加PC端自带源代码

Lua5.1中加载dll动态链接库的方法

主要介绍了Lua5.1中加载dll动态链接库的方法,本文讲解了加载专门为lua写的扩展dll的方法和加载不是专为lua写的扩展dll的方法,需要的朋友可以参考下

GTA5修改器YimMenu实战攻略:从3分钟编译到Lua脚本全掌握

战局被一秒炸穿、队友集体掉线、游戏随机闪退——这类糟心事,GTA5线上玩家多少都经历过。想自保、想反击、又想玩得更爽?**YimMenu**,一款开源的GTA5修改器,把"防崩溃"和"体验增强"打包成了同一个答案,而且完全免费。 ## 先讲个让人血压飙升的场景 你正开着装满货的车在洛圣都街头赶路,屏幕上突然弹出一段奇怪的花屏,紧接着整个战局的人都被弹回桌面。重新启动游戏、排队、加载,半小时的进

gitblog_01054的博客 449

转录组数据去批次方法整理(combat,combat-seq,removeBatchEffect)

正是因为这些非生物学的因素存在就有可能会导致我们的结果偏离真实的情况,那么实际分析的过程中研究者应当评估是否存在批次效应,并决定是否要进行去批次处理。批次效应是指样本在不同批次处理及测量的情况下引入与生物学情况不相关的技术误差,比如不同试剂耗材,不同操作者,不同的实验时间等。combat函数是基于贝叶斯框架下的调整数据批次效应的函数,主要适用于已经被过滤和标准化后的数据(combat-seq函数是基于二项回归分布下的调整数据批次效应的函数,主要适用于。值得注意的是,即使使用了所谓的去批次效应的工具,

zfyyzhys的博客 7862

手游热更新方案--Unity3D下的CsToLua技术

作者:王攀峰, 腾讯游戏客户端开发 工程师 商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处。 原文链接:http://wetest.qq.com/lab/view/387.html WeTest 导读 CsToLua工具将客户端 C#源码自动转换为Lua,实现热更新,本文以麻将项目为例介绍客户端技术细节。 麻将项目架构 其中ChinaMahjong-CSLua为...

wetest_tencent的博客 1764

高通Camera HAL3调试实战:如何用camxoverridesettings.txt高效抓取日志与dump图像数据

本文深入探讨了高通Camera HAL3调试中camxoverridesettings.txt文件的高效应用,重点介绍了如何通过该文件精准控制日志输出级别与dump图像数据,帮助开发者快速定位移动影像系统中的问题。文章详细解析了日志分级配置、图像数据捕获技巧及典型问题排查流程,为高通Camera HAL3项目开发提供了实用技术点。

weixin_30315905的博客 861

EEGLAB+ERPLAB实战:从.cnt文件到情绪ERP差异波,一份避坑指南

本文详细介绍了使用EEGLAB和ERPLAB处理Neuroscan的.cnt格式脑电数据的全流程,从数据导入、预处理到情绪ERP差异波生成。重点解决了采样率验证、事件标记检查、重参考选择、滤波策略与ICA组合等实操难题,并提供了情绪图片ERP研究中P1、EPN和LPP成分的分析技巧,帮助研究者避免常见错误,提升数据处理效率。

weixin_26795617的博客 264

某修仙肉鸽游戏协议逆向分析折腾记录

游戏使用lua-protobuf库处理消息序列化,协议定义的加载方式是这样的:1234567891011121314151617181920212223242526272829ProtobufParser.lua 核心逻辑预编译的protobuf定义文件基础消息类型定义服务端协议定义异步加载二进制protobuf定义forinifandifnotreturnfalseendelsereturnfalseendendreturn。

2503_90751789的博客 2310

深度解析:C# Modbus TCP协议解析与异常处理(工控上位机必备)

协议解析要精准:掌握MBAP头和PDU的结构,尤其是常用功能码的请求/响应格式,避免因字节处理错误导致通信失败;异常处理要全面:覆盖通信层、协议层、数据层的所有异常类型,针对工业场景制定重试、重连、滤波等策略;资源管理要规范:使用释放资源,采用连接池复用连接,避免端口泄露;工业场景要适配:结合工控现场的特点(网络波动、电磁干扰、设备忙),优化通信效率和数据处理逻辑。通过以上解析和策略,可确保C#上位机与工业设备的Modbus TCP通信具备高稳定性、高可靠性、高容错性,满足工控领域的严苛要求。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 997

GTA5联机老是崩溃?3步上手YimMenu,免费修改器帮你安心畅玩

你正开着心爱的跑车在洛圣都街头兜风,屏幕突然一黑,游戏退回桌面。这已经是今晚第三次了。别急着怪电脑——你大概率遇上了联机战局里的恶意炸房。**YimMenu**就是专门治这个的:一款免费的GTA5修改器,核心使命是挡住五花八门的公共崩溃攻击,顺带把整体游戏体验拉高一档。 ## 它到底解决了什么:给游戏穿件防弹衣 直接说,YimMenu不是一个"花里胡哨秀功能"的玩具,而是一个"先保命再谈爽"的

gitblog_00949的博客 892

数美device_fingerprint、device_id、hmac生成

device_fingerprint、hmac、device_id参数分析与解读

吴秋霖的博客 2875

QCC304x系列开发教程(实战篇)之5.2 QCC3040之提示音

earbud_init.c中,初始化table中UiPrompts_Init /*! \brief Table of initialisation functions */ static const init_table_entry_t appInitTable[] = { ......... {UiPrompts_Init, 0, NULL}, ......... } ui_prompts.c中是提示音音处理的主要逻辑和配置源文件 函数static void uiPro...

心跳包的博客 2393

Vue Router 编程式导航完全指南:push、replace、go 与 History 操作原理

编程式导航(Programmatic Navigation)是 vue-router(Vue 2 官方路由)中除 `<router-link>` 声明式跳转之外的核心导航能力,本文以 [docs/kr/guide/essentials/navigation.md](https://link.gitcode.com/i/860ebaac0aa77184adc57c3bf4c9e957)(英文原版见

gitblog_00792的博客 913

配置 SAP Fiori 服务的 ICF 节点:从 SICF 激活到访问链路打通的完整实践

在SAP Fiori项目实施中,ICF节点配置是关键前置条件却常被忽视。ICF(Internet Communication Framework)作为HTTP请求入口,需要通过SICF事务码激活相关服务节点,否则即使应用开发完善,用户仍可能遇到页面无法访问等问题。典型问题表现为:磁贴可点击但页面空白、资源加载失败等。激活路径主要涉及三组节点:bsp分支下的管理入口、ui5_ui5分支下的应用资源,以及public/bc下的公共资源。项目实施中需特别注意同名服务在不同分支下的差异化作用,确保完整链路通畅。IC

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 264

YimMenu使用指南:GTA5免费增强菜单从安装到进阶防护全攻略

如果你玩过 GTA5 线上模式,大概率经历过这样的时刻:好好的公开战局里,突然屏幕一黑、游戏崩溃,或者被莫名炸死、拉进诡异场景。这些"事故"背后,往往是其他玩家的恶意捣乱。而 YimMenu,正是一款专为 GTA5 打造的免费开源增强菜单,它的核心卖点不是花哨的作弊功能,而是**针对公开崩溃和恶意攻击的全面防护**,顺带把整体游戏体验提升一个档次。这篇文章会带你从零开始:搞懂它能做什么、如何编译安

gitblog_00137的博客 232

【图像拼接(Image Stitching)】关于【图像拼接论文精读】专栏的相关说明,包含专栏使用方法、阅读顺序、创新思路、文章汇总、源码汇总、数据集汇总等。总之,【图像拼接论文相关】看这一篇就够了

为什么会有这篇文章?因为专栏简介里写不下太多东西,只能通过这篇文章和大家交流,算是一个专栏阅读指南吧。说点心里话本来吧,我只想用优快云来记录自己学习【图像拼接】领域论文的过程,对每篇文章有个细致的理解,方便自己反复查阅。设置为付费也是因为涉及论文和本人其他项目需要,防止查重和其他问题,所以价格最开始设置的是专栏付费价格里最高的。起初,确实没有人看,一切也都平淡地度过着。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 4万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

从商业Unity源码看手游工程化:热更新、UI框架与资源管理实战

移动游戏开发中,Unity项目的工程化能力决定了产品能否支撑千万级流水和长期迭代。热更新是商业手游绕不开的架构决策,通过Lua脚本与AssetBundle机制,将可修改的内容逻辑与引擎层分离,实现不发版即可修Bug、调数值。UI框架则是交互体验的地基,UIManager配合对象池管理界面生命周期,解决异步加载竞态与跳转栈维护问题。资源管理层面,引用计数、异步加载与GC控制是应对复杂场景和长线运营的关键手段。这些能力在实际项目中,例如商业Unity源码的架构分析中,往往体现为模块解耦、数据表驱动、逻辑帧与表现

weixin_30972263的博客 140

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

windows 搞搞SWIG系列

windows下安装SWIG 地址 https://sourceforge.net/projects/swig/files/   我进入swigwin,下载了swigwin-4.0.1.zip 解压之后这个样子   然后直接配置环境变量就好了 根本不需要安装   还可以输入swig --help看看成功了没有 ...

fgh123的博客 591

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

使用CheatEngine逆向实战:绕过游戏CRC内存保护机制

循环冗余校验(CRC)是一种广泛用于验证数据完整性的算法,它通过生成数据的“指纹”来检测任何未经授权的修改。其原理基于多项式除法,能够高效、敏感地识别数据变化,因此在软件保护、网络通信和存储校验中具有重要技术价值。在游戏安全领域,CRC常被用作内存保护机制,周期性校验关键代码或数据的完整性,以防止外挂篡改。理解CRC检测的典型工作流程——包括初始化、周期性计算、比对与响应——是进行安全分析和对抗的基础。通过动态分析工具定位检测逻辑和关键跳转,可以学习到如何绕过此类保护。本文以游戏修改为切入点,结合Cheat

weixin_30252709的博客 427

Unity主程实战指南:C#深度优化、架构设计与热更新方案解析

在Unity游戏开发中,C#语言是构建游戏逻辑的核心基础。理解其内存管理机制,如垃圾回收(GC)原理与值类型引用类型的本质区别,是编写高性能代码的关键。通过对象池等设计模式优化内存分配,能有效避免移动端卡顿。异步编程方面,需掌握协程与async/await的底层机制,根据I/O密集或计算密集型任务合理选型,确保主线程流畅。这些技术最终服务于构建可维护的大型项目架构,例如通过模块化分层与依赖注入管理复杂依赖。而在移动游戏领域,热更新技术是支撑游戏持续运营的刚需,它要求开发者深入理解资源管理、代码动态加载与版本

weixin_30553777的博客 324

Python 最反人类、最不合理的设计缺陷 ——强制缩进

有时纯粹自已想实现啥就做啥,反而可以做的更完美,处处受限,就变成一个半成品一样了。一个处处受限、语法不自由、结构不清晰、靠第三方库续命的半成品脚本引擎。

201

可扩展FDA:实时示波器从测量工具到分析平台

实时示波器是电子工程师观察信号时域与频域特征的核心工具,内置FFT和频域分析(FDA)功能虽能完成基础频谱查看,但受限于固定窗函数、不可调的FFT点数以及封闭的运算流程,难以应对自定义频谱分析需求。可扩展FDA(User-Extensible FDA)从信号处理链路出发,通过定义插件接口,将用户自研的窗函数、频域算法或指标提取逻辑注入示波器实时数据流,使仪器从“固定功能计算器”进化为开放分析平台。工程上聚焦五层处理流水线、插件协议与线程模型、实时性预算、帧重叠优化以及调试校准等关键环节。技术价值在于:工程师

weixin_34184561的博客 300
上一篇: easyui两个控件学习
下一篇: 正太分布
erlang_hell
博客等级 码龄14年 57粉丝 89原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值