目录

python调用lua

python调用lua

一、引言

上一周应该某个特殊需求。需要在服务器端搭建一个lua执行环境。lua本身又是嵌入语言。在语言本身上又一定的局限性。所以我打算把lua嵌入到python/java中。做调研的时候,java的嵌入较为麻烦,出现了各种问题。后来确定用python来作这个环境。这样能用上python 的协程、多线程。这里说说python中嵌入lua的问题。

二、环境建立

python中又一个扩展叫 lupa 。这个扩展用于在python中嵌入lua。安装

pip install lupa
  • 1

我只在liunx/oxs中安装过。在liunx上一下就成功了。oxs上出了些问题。可以google出来。

三、例子

在两个线程中执行lua脚本。这里需要两个文件test.lua与test.py.

1.test.lua
  • -- Time:2016/07/15
    
    function test1(params)
        return 'test1:'..params
    end
    
    function test2(params)
        return 'test2:'..params
    end
    
    -- 入口函数,实现反射函数调用
    function functionCall(func_name,params)
        local is_true,result
        local sandBox = function(func_name,params)
            local result
            result = _G[func_name](params)
            return result
        end
        is_true,result= pcall(sandBox,func_name,params)
        return result
    end

在这个文件中定义了三个函数,test1,test2为测试函数。functionCall用于实现统一的函数调用方式。

2.test.py
  • import traceback
    from lupa import LuaRuntime
    import threading
    
    class Executor(threading.Thread):
        """
            执行lua的线程类
        """
        lock = threading.RLock()
        luaScriptContent = None
        luaRuntime = None
    
        def __init__(self,api,params):
            threading.Thread.__init__(self)
            self.params = params
            self.api = api
    
        def run(self):
            try:
                # 执行具体的函数,返回结果打印在屏幕上
                luaRuntime = self.getLuaRuntime()
                rel = luaRuntime(self.api, self.params)
                print rel
            except Exception,e:
                print e.message
                traceback.extract_stack()
    
    
        def getLuaRuntime(self):
            """
                从文件中加载要执行的lua脚本,初始化lua执行环境
            """
    
            # 上锁,保证多个线程加载不会冲突
            if Executor.lock.acquire():
                if Executor.luaRuntime is None:
                    fileHandler = open('./test.lua')
                    content = ''
                    try:
                        content = fileHandler.read()
                    except Exception, e:
                        print e.message
                        traceback.extract_stack()
    
                    # 创建lua执行环境
                    Executor.luaScriptContent = content
                    luaRuntime = LuaRuntime()
                    luaRuntime.execute(content)
    
                    # 从lua执行环境中取出全局函数functionCall作为入口函数调用,实现lua的反射调用
                    g = luaRuntime.globals()
                    function_call = g.functionCall
                    Executor.luaRuntime = function_call
                Executor.lock.release()
    
            return Executor.luaRuntime
    
    
    if __name__ == "__main__":
    
        # 在两个线程中分别执行lua中test1,test2函数
        executor1 = Executor('test1','hello world')
        executor2 = Executor('test2','rudy')
        executor1.start()
        executor2.start()
        executor1.join()
        executor2.join()
  • 这个文件中定义了lua执行线程类。用于具体执行lua代码。具体作用参见代码注释。
3.执行结果

如图

https://i-blog.csdnimg.cn/blog_migrate/9cc1dbcf402408d194fb16afadc42a92.png