转载请标明出处: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#是如何实现的,当然写的比较简陋,还有很多细节需要推敲,大家可以翻看自己的项目代码,留言讨论

Lua和C#调用探秘的更多相关文章

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

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

  2. tengine lua 开源一 调用内部接口高效发送文件

    tengine  lua 开源一 调用内部接口高效发送文件 开源自己封装的sendfile 模块,可以高效的通过lua发送文件 源码地址:https://github.com/weinyzhou/Lu ...

  3. ubuntu配置lua环境,并进行c与lua的相互调用

    1.安装lua环境 先查看一下apt可获取的lua版本 我们选择lua5.1版本进行安装 sudo apt install lua5.1 安装完之后测试一下是否安装成功,如果可以正常使用,则lua环境 ...

  4. (原)lua使用ffi调用c程序的函数

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5812763.html 参考网址: http://luajit.freelists.narkive.co ...

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

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

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

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

  7. openresty+lua做接口调用权限限制

    说明:openresty可以理解为一个服务器它将nginx的核心包含了过来,并结合lua脚本语言实现一些对性能要求高的功能,该篇文章介绍了使用openresty 1.purview.lua --调用j ...

  8. lua不同模块调用

    一.起因 由于准备把lua加入的系统中,还需把字符串解析json.下了个json的lua,目前还没有搞定.但是一个lua,调用其他lua文件模块,目前刚刚搞定. 暂作记录. 二. 模块调用测试 1. ...

  9. lua使用ffi调用c程序的函数

    参考: https://blog.csdn.net/weiwangchao_/article/details/16880401   http://luajit.org/ext_c_api.html h ...

随机推荐

  1. EasyUI中, datagrid用loadData方法绑定数据。

    $("#dg").datagrid("loadData", { , " }, { "ck": "1", &qu ...

  2. 再一次, 不要使用(include/require)_once

    本文地址: http://www.laruence.com/2012/09/12/2765.html 最近关于apc.include_once_override的去留, 我们做了几次讨论, 这个APC ...

  3. csrf学习笔记

    CSRF全称Cross Site Request Forgery,即跨站点请求伪造.我们知道,攻击时常常伴随着各种各样的请求,而攻击的发生也是由各种请求造成的. CSRF攻击能够达到的目的是使受害者发 ...

  4. 微信开发之SVN提交代码与FTP同步到apache的根目录

    SVN是协同开发的,版本控制器,就是几个人同时开发,可以提交代码到SVN服务器,这样就可以协同开发,一般是早上上班首先更新下代码,然后自己修改代码 工作一天之后,修改代码之后,下班之前,更新代码,然后 ...

  5. 在bootstrap中让竖向排列的输入框水平排列

    在bootstrap中可以使用自带的样式标记来控制样式,但是同时可以利用最原始的css样式来解决达到需求 如下所示可以看出来两个inline-block就可以使得两个水平排列 block和inline ...

  6. MySQL Group Relication 部署环境入门篇

      一:环境介绍   cenos 6.7 版本 数据库的版本5.7.19 二:部署规划单机多实例的部署   端口号 数据目录  group_repplicatoon 通信接口   3307 /data ...

  7. pygame事件之——控制物体(飞机)的移动

    近来想用pygame做做游戏,在 xishui 大神的目光博客中学了学这东西,就上一段自己写的飞机大战的代码,主要是对键盘控制飞机的移动做了相关的优化 # -*- coding: utf-8 -*- ...

  8. Postgres中postmaster代码解析(上)

    之前我的一些文章都是在说Postgres的一些查询相关的代码.但是对于Postgres服务端是如何启动,后台进程是如何加载,服务端在哪里以及如何监听客户端的连接都没有一个清晰的逻辑.那么今天我来说说P ...

  9. pthon/零起点(一、集合)

    pthon/零起点(一.集合) set( )集合,集合是无序的,集合是可变的,集合是可迭代的 set()强型转成集合数据类型 set()集合本身就是去掉重复的元素 集合更新操作案列: j={1,2,3 ...

  10. java同时连接db2和mysql的程序

    db2的jar包安装参见:http://www.cnblogs.com/zifeiy/p/7918554.html 代码: package com.anbank.datafetch; import j ...