转载请标明出处:http://www.cnblogs.com/zblade/

在实际的项目中,大部分业务逻辑 程序员只需要负责lua层编写逻辑即可,或者在c#层添加一些静态函数,供lua层调用。那么对于具体的相互之间的交互,又是如何进行的?本文就写一写个人的一些探究笔记吧。本文会写很多代码,我就用截图来展示吧,编辑写代码不大方便,有点蛋疼~

一、c#函数的导出

我就从外部接口开始理一遍整体思路吧,想了一下,还是从代码思路来解释比较容易。

首先我们的工程中都会有一个slua的导出接口:

这样的一个接口,是用来将UnityEngine中的类导出的实现API,其整体的思路是:

1)首先加载UnityEngine这个程序集:

Assembly assembly = Assembly.Load("UnityEngine")

2)然后获取资中的可导出类型:

Type[] types = assembly.GetExportedTypes();

3) 做一次过滤,主要是对于某些需要导出的类和不需要导出的类做一次过滤剔除和添加,这个不同项目不一样,不做展示;

4)将这些过滤后的类型,逐个做一次导出,比如相机类,可以导出为:

5)将这些导出的类Lua_xxx合并在一起作为一个Bind, 提供一个静态获取方法GetBindList()

这是第一步,完成对c#和unity中的方法导出,将每个不同程序集中的类中的方法和属性都暴露出来,做一个导出。

二、导出的c#文件的注册到Lua虚拟机中

这部分需要结合游戏的启动来理解,在游戏的启动时刻,我们都会启动一个Lua的虚拟机,比如这样:

在启动虚拟机后,需要执行虚拟机的Init操作:

m_LuaSvr.init(xxxx)

在这个函数中,执行Bind的操作:doBind

其中的关键操作为collectBindInfo, 这个函数分为2部分:

1)获取当前程序集,以及程序集中设置为LuaBinderAttribute的类型:

2)根据获取的类型,逐个反射执行第一部分最后的GetBindList函数:

这样通过c#的反射,就可以动态的获取前面导出的所有LuaXXX类文件了,回到Bind操作,对于这些获取的Lua_XXX文件,执行Lua虚拟机的注册操作:

action(L)

也就是导出文件中的reg操作:

看看其操作,首先是newtable的操作:

创建2个table,分别用来做static和instance的填充,然后填充的操作addMember:

对于不同的参数,会重载不同的addMember操作,这儿就举例一个,pushValue就是将func注册到该table中:

LuaDll.lua_pushcclosure(L, function, 0)

就是将该函数填充到lua表中,可以通过key名的查找来获取该函数,从而执行相关的调用。

最后会在该reg操作中为该类创建一个metatable

回到最初的,不断的循环执行,就可以加载整个c#相关导出类到Lua虚拟机中

总结:到现在为止,可以知道整个c#函数在导出过程中的操作,在启动时候如何通过程序集和反射来实现动态的加载,最后Lua的虚拟机中都会注册前面导出的类文件的相关函数和属性。

而我们已经知道,lua文件在执行的时候,是会编译成字节码在lua的虚拟机中执行的,这样lua的字节码和c#的导出文件,都在同一个环境中执行,调用pcall就可以相互的执行和调用了。

写这篇文章是基于偶然翻看到老外写的一个在unity中用c++做脚本来编写游戏逻辑,并且实现了c#和c++之间的相互交互调用,所以我也翻看了一下c#是如何实现的,当然写的比较简陋,还有很多细节需要推敲,大家可以翻看自己的项目代码,留言讨论

转载于:https://www.cnblogs.com/zblade/p/8927127.html

Lua和C#调用探秘相关推荐

  1. linux c程序调用脚本,C程序与Lua脚本相互调用

    Lua脚本是一种可用于C程序开发/测试的工具,本篇介绍一下C程序与Lua脚本如何进行相互调用,更加详细的操作参见<Programing in Lua>.本文分为3个部分:1.Windows ...

  2. Lua脚本如何调用C/C++模块,Windows以及Linux版本演示

    Windows下 我用的是vs2019,由于Windows下不像Linux可以直接直接安装lua程序直接运行lua代码,所以这里我们演示的是,通过c/c++调用lua脚本,lua脚本再调用其他的C/C ...

  3. Lua跨文件调用方法

    Lua跨文件调用方法 创建一个lua文件用于被调用 创建一个名为raspberry的文件,后缀为.lua,然后将下面的代码放进去 Raspberrypi={};Runstate=false;Sayhe ...

  4. 如何将C++代码封装成C模块,适配Python、Lua和C++调用。多种语言(C++、python和lua)调用C++封装的看门狗sdk模块

    概述 示例程序仓库路径:https://gitee.com/liudegui/test_dogservice 示例程序是对看门狗模块的封装,已在windows平台测试,代码理论上可直接支持Linux平 ...

  5. Lua学习笔记6:C++和Lua的相互调用

    曾经一直用C++写代码.话说近期刚换工作.项目组中的是cocos2dx-lua,各种被虐的非常慘啊有木有. 新建cocos2dx-lua项目.打开class能够发现,事实上就是C++项目啦,只是为什么 ...

  6. 实战:Nginx集成Lua脚本并调用memcached

    之前在阿里云的centos系统上已经安装过nginx,但是没有安装lua所需的模块,因此重新编译nginx来扩展lua模块. ngx_lua_module 是一个nginx http模块,它把 lua ...

  7. 安卓JAVA调用lua_android中java与lua的相互调用

    Android Studio Lua环境配置 开发环境 1. Android Studio 3.5 2. java sdk: 1.8.0 3.android sdk:28 配置环境 添加lua支持语法 ...

  8. Unity热更新学习(二) —— ToLua c#与lua的相互调用

    tolua 下载地址:http://www.ulua.org/index.html c#调用lua的方法,tolua的官方例子提供了很多种.我初步学了一种在做项目使用的方法.通过DoFile方法执行l ...

  9. lua 文件相互调用

    假设 demo1.lua 想调用 demo2.lua,那么需要在demo2.lua中如下设置: local _M = {}function _M.test1()return "hello w ...

最新文章

  1. 优秀!这位70后硕士,入围中国工程院院士候选人!
  2. linux系统中建立网络白名单,Linux下设置防火墙白名单(RHEL 6和CentOS 7)的步骤
  3. 10个免费的javascript富文本编辑器(jQuery and non-jQuery)
  4. python long函数_python 内置函数
  5. js面向对象-组合使用构造函数模式和原型模式(使用最广泛、认同度最高)
  6. html3d上下翻转4面效果,花式实现图片3D翻转效果
  7. postmessage 游戏窗口内无效_前端的微前端在交通项目内的应用实践
  8. 查找ipa包,删除接的ipa包
  9. linux gpt引导分区,linux 引导gpt分区windows及clover
  10. JSP教程第4讲笔记
  11. python集合操作班级干部竞选演讲稿_【热门】竞选班干部演讲稿集合8篇
  12. MIT数字经济研究:建平台要以“网络效应”为目标
  13. 服务器如何与智能家居通讯协议,智能家居通信协议优缺点比较
  14. 使用Guacamole实现远程桌面控制
  15. 触动千亿电商市场 BitCherry星耀雅加达
  16. GAN论文逐段精读【论文精读】
  17. git 怎么回退已经push的版本_git push 操作代码回退
  18. LD3320语音识别模块:LDV7模块使用详解
  19. 华东师范2018研究生复试上机题题解
  20. leveldb之arena

热门文章

  1. SAP标准培训课程C4C10学习笔记(一)第一单元
  2. 一个用JavaScript生成思维导图(mindmap)的github repo
  3. php自动计数,PHP 实现精确统计在线人数功能
  4. python线程问题_Python线程问题
  5. python全局变量的声明和使用_Python二级(07)——函数和代码复用
  6. java过滤器放行_过滤器学习
  7. cocos中如何让背景模糊_Cocos2d-x shader学习2: 模糊(Blur)
  8. server2019远程服务器ipv4地址_Windows Server 2019远程桌面服务配置和授权激活
  9. 计算文本相似度_Python文本相似性计算
  10. webpack 合并压缩_webpack的运用