解释型语言和编译型语言如何交互?以lua和c为例

转自http://my.oschina.net/mayqlzu/blog/113528ios

问题:编程

最近lua很火,由于《愤怒的小鸟》使用了lua,ios上有lua解释器?它是怎么嵌入大ios中的呢?lua的官网说:"lua is an embeddable scripting language",怎么理解呢?怎么在你本身的程序里嵌入lua解释器呢?若是能够在个人程序中嵌入了lua,那是否意味着我能够今后用lua编程了呢?windows

带着这些问题,打算在个人windows笔记本上作个实验,目标是在windows上跑一个lua的解释器,而后用lua语言写一个程序,跑在这个解释器之上,也就说最后的效果是:eclipse

(上) lua program -> lua解释器 -> windows (下)编辑器

或者是:函数

(上) lua program -> lua解释器 -> my c program -> windows (下)工具

实践:ui

1) 下载lua源码;lua

2) 用eclipse+mingw编译lua解释器的源码spa

eclipse+mingw编译环境我以前就已经搭好了,有兴趣的同窗能够参考个人另外一篇文章,固然你也能够用其余编译工具,好比visual Studio;

创建一个空白c工程,project type选Executable->Empyt Project;

导入src目录下的全部文件,包括.c, .h和Makefile文件;

点击build,开始编译;

遇到编译错误:main()重定义,lua.c和luac.c里分别有一个main(),lua.c是解释器的源码,luac.c是编译器的源码,咱们此时要的是解释器,因此从工程删除luac.c,从新编译,经过,生成lua.exe;

没想到lua的源码和Makefile写得这么好,这么顺利就编译经过了,网上说lua是用标准c写的,只要是支持标准c的编译环境都能顺利的编译它;

3) 运行编译出来的解释器

找到lua.exe所在的目录,在这个目录下先准备一个用lua写的程序,好比hello.lua,包含代码:print "hello lua";

打开一个windows的cmd窗口,cd到编译结果lua.exe所在的目录,调用lua解释器,执行hello.lua程序,命令为:lua.exe "hello.lua",(我以前从官网下载了一个编译好的lua解释器和SciTE编辑器,我看到SciTE编辑器就是用这个命令调用lua解释器的)看到窗口输出hello lua,太好了,至此,我亲手编出了一个lua解释器,能够跑在个人windows系统之上;

4) 下一步,怎么在个人c程序里调用lua解释器?

哦,知道了,个人c程序调用windows的接口将lua.exe跑起来,同时把hello.lua文件做为参数传给lua.exe,不就好了。

在你的main.c中,能够用相似这样的代码调用lua.exe:system("C:\\some_path\\lua.exe -e \"hello.lua\" " )

5) lua解释器执行hello.lua的时候,若是hello.lua想调用一个本地库foo.dll中的foo()函数,foo.dll是foo.c编译生成的,怎么办?

稍等,我正在作...

6) foo.c怎么调用hello.lua中的函数?

写到这儿,忽然明白了,解释型语言和编译型语言之间的相互调用没什么神秘的,仍是以lua和c为例,

a)先看lua怎么调c?

所谓的lua调用c,是指foo.lua调用bar.c中的代码,foo.lua自己只是一段源码,不能执行的,必须由lua解释器来执行,lua解释器是一个可执行程序,能够运行,foo.lua能够当作是解释器程序运行过程当中读取的一个配置文件,根据”配置文件foo.lua“内容的不一样作不一样的事情,若是”配置文件foo.lua“说调用bar.c中的bar()函数,那么解释器lua.exe就去调用了,假设此时bar.c也已经编译成了二进制bar.dll,那既然lua.exe和bar.dll是同一个平台(好比windows)上的二进制程序,互相之间的调用就没什么稀奇了吧,就跟你写一个简单的main.exe调用bar.dll同样了;

b)再看c怎么调用lua?

所谓的c调用lua,是指foo.c调用bar.lua中的代码,咱们先要把foo.c编译成一个可执行程序foo.exe,这样才能执行嘛,但是被调用方bar.lua只是一个包含lua代码的源文件,不是二进制的(咱们如今是在讨论解释器,不考虑lua预编译成二进制的状况),没法调用,因此咱们就要借用lua解释器了,因此整个流程就是:foo.exe -call-> lua解释器(可执行程序)-读取-> bar.lua,foo.exe其实只和lua解释器打交道,告诉它我要调用某个函数,而后由解释器负责去找到这个函数并调用;

综上,你会发现,不论是lua调c仍是c调lua,他们都不是直接交互的,由于lua程序只是一堆”死“的源代码,像一个配置文件同样,不能执行的,因此就须要一个中间人”lua解释器“,只要c程序和lua解释器之间约定好接口,那么实现c和lua之间的调用就是很天然的事情了,没什么神秘的。

最后给出一个示意图:

一个用c写的程序,已经编译成二进制 <--> 用c写的lua解释器,已经编译成二进制 -> 一个lua写的程序,只能被解释器”被动“地读取,不能”主动“地执行

相关文章
相关标签/搜索