Lua 中多线程用法 for Win32Exts

Lua 中多线程用法 for Win32Exts

 

           目前 Lua 中并没有 真正的抢占式 thread 的概念,只有一个类似的协程:coroutine 对象,

同一时间只能运行一个 coroutine ,并且需要显式的进行切换才能执行。与实际应用需求相差甚远。

(coroutine 用法参见: https://blog.csdn.net/wzzfeitian/article/details/8832017)

 

 Win32Exts for Lua 中实现了真正的 抢占式线程 thead 的相关操作,并做了各种强化。

      Win32Exts 是一个支持多种脚本语言(VBS, JS, Lua, Python, Java, CEF框架等 )的 Win32 扩展库, 通过它,你能够像C/C++ 一般

调用任意系统或者第三方API,实现强大的功能需求。

 库地址:  https://github.com/tankaishuai/win32exts_for_Lua

 

 

用法:

1、创建线程: 

      h = win32exts.create_thread( lua_file, [arg] )

      h = win32exts.create_thread( lua_script, [arg] )

      成功返回线程对象 h,失败返回 nil。在 Lua 脚本里面通过全局变量 __args 获取传入参数。

      以上 可选参数 arg 只能传入一个整数给新线程。

 

      如果希望更灵活的传入各种参数,可以使用下列增强接口:

      h = win32exts.create_thread_v2( lua_file, [arg1, arg2, arg3 ... ] )

      h = win32exts.create_thread_v2( lua_script, [arg1, arg2, arg3 ... ] )

      其中参数个数以及类型随便(除了Lua的thread与function这两种对象不支持之外,userdata类型弱支持),

      也可以包装成一个 table 对象传入。

      例如:

      h = win32exts.create_thread_v2( "C:\\test.lua", "第一个参数", 2, {[true] = false}, 3.14, "第五个参数" )

      或者以上等价于:

      tbl = { "第一个参数", 2, {[true] = false}, 3.14, "第五个参数" }

      h = win32exts.create_thread_v2( "C:\\test.lua", tbl )

      在 Lua 脚本里面通过全局变量 __args[1], __args[2], ... , __args[5] 获取传入的参数。

 

 

2、结束线程并获取返回值:

       ret = win32exts.end_thread( h, [timeout] )

       ret 为 lua 脚本返回值。 在 Lua 脚本里面通过全局变量 __ret 设置返回值。

 

      例如, 简单地获取传入参数,加一后返回之:

      > require "win32exts"

      > script = [[print("args:" .. __args)]] .. "\n" .. [[__ret = __args+1]]

      > h = win32exts.create_thread(script, 333)

      args:333

 

      > print( win32exts.end_thread(h, 0) )
      334

 

      大块数据 buffer 也可以考虑先分配一块内存,然后传入指针给线程:

 

      > script2 = [[ print(win32exts.read_wstring(__args)) ]]
      > g_buf = win32exts.malloc(520)
      > win32exts.write_wstring(g_buf, 0, -1, "~~~test_string_data~~~")
      > h = win32exts.create_thread(script2, g_buf)
           ~~~test_string_data~~~   

 

 

3、除了支持创建本地线程之外,win32exts ver 38.2020.2.21  以后版本也支持创建远程线程

     亦即使得目标 Lua 脚本运行在其它进程之内: 

      h = win32exts.create_remote_thread( process_id, lua_file, [arg] )

      h = win32exts.create_remote_thread( process_id, lua_script, [arg] )

      以及增强接口:

      h = win32exts.create_remote_thread_v2( process_id, lua_file, [arg1, arg2, arg3 ... ] )

      h = win32exts.create_remote_thread_v2( process_id, lua_script, [arg1, arg2, arg3 ... ] )

      使用方法与本地线程完全一致。

      获取远程Lua脚本返回值使用:

      ret = win32exts.end_remote_thread( h, [timeout] )

      

 

4、以上都是直接在当前进程或者其它进程上面 新建线程执行 Lua,

     如果想在当前已有的线程上直接执行 Lua脚本,可以使用下列接口:

      h = win32exts.inject_remote_thread( thread_id, lua_file, [arg] )

      h = win32exts.inject_remote_thread( thread_id, lua_script, [arg] )

      以及增强接口:

      h = win32exts.inject_remote_thread_v2( thread_id, lua_file, [arg1, arg2, arg3 ... ] )

      h = win32exts.inject_remote_thread_v2( thread_id, lua_script, [arg1, arg2, arg3 ... ] )

 

       例如,尝试取指定线程队列中 的一个消息:

     code = [=[

            win32exts.load_sym("user32", "*")

            pMsg = win32exts.malloc( 0x20 );

            win32exts.PeekMessageW( pMsg, nil, 0, 0, 0)

     ]=]

     h = win32exts.inject_remote_thread( thread_id, code )

 

     除了以上接口之外,如果目标线程含有用户界面,v41 以后版本还可以使用以下几个接口:

      ret = win32exts.inject_remote_window( hwnd, lua_file, [arg] ) 

      ret = win32exts.inject_remote_window( hwnd, lua_script, [arg] )

      ret = win32exts.inject_remote_thread_ex( thread_id, lua_file, [arg] )

      ret = win32exts.inject_remote_thread_ex( thread_id, lua_script, [arg] )

      以及增强接口:

      ret = win32exts.inject_remote_window_v2( hwnd, lua_file, [arg1, arg2, arg3 ... ] )

      ret = win32exts.inject_remote_window_v2( hwnd, lua_script, [arg1, arg2, arg3 ... ] )

      ret = win32exts.inject_remote_thread_ex_v2( thread_id, lua_file, [arg1, arg2, arg3 ... ] )

      ret = win32exts.inject_remote_thread_ex_v2( thread_id, lua_script, [arg1, arg2, arg3 ... ] )

 

 

5、除了线程之外,还有几个异步操作相关的函数可以直接使用:

 

      线程池操作

      is_ok = win32exts.queue_task( lua_file, [arg] )

      is_ok = win32exts.queue_task( lua_script, [arg] )

      is_ok = win32exts.queue_task_v2( lua_file, [arg1, arg2, arg3, ... ] )

      is_ok = win32exts.queue_task_v2( lua_script, [arg1, arg2, arg3, ... ] )

 

      APC操作

      is_ok = win32exts.queue_apc( lua_file, [arg] )

      is_ok = win32exts.queue_apc( lua_script, [arg] )

      is_ok = win32exts.queue_apc_v2( lua_file, [arg1, arg2, arg3, ... ] )

      is_ok = win32exts.queue_apc_v2( lua_script, [arg1, arg2, arg3, ... ] )

   

      以及远程 APC操作

      is_ok = win32exts.queue_remote_apc( thread_id, lua_file, [arg] )

      is_ok = win32exts.queue_remote_apc( thread_id, lua_script, [arg] )

      is_ok = win32exts.queue_remote_apc_v2( thread_id, lua_file, [arg1, arg2, arg3, ... ] )

      is_ok = win32exts.queue_remote_apc_v2( thread_id, lua_script, [arg1, arg2, arg3, ... ] )

 

     功能相当强大。

 

 

     例如,以下代码查找 某聊天软件进程,并在其进程中执行指定的 Lua 脚本, 显示消息框:

     code = [=[

           win32exts.load_sym("*", "*")                                                         --加载所有库

           win32exts.HideModuleByModule( win32exts.current_dll() )      --把自己隐藏了,这样别人就无法发现了←___←‘

           __ret = win32exts.MessageBoxA( __args[1], __args[2], __args[3],  1)    --在里面弹出我们的消息

      ]=]

 

      win32exts.load_sym("*", "*") 

      hWnd = win32exts.FindWindowA( "TXGuiFoundation", "QQ" ) 

      g_buf = win32exts.malloc(4)

      win32exts.GetWindowThreadProcessId( hWnd, g_buf )                 --以上获取进程Id,懂C/C++的毫无理解难度

      dwProcessId = win32exts.read_value(g_buf, 0, 4)

      h = win32exts.create_remote_thread_v2( dwProcessId, code,  hWnd, "请点击:http://my.com",  "这是官方的推送哦!!")

      if  win32exts.end_remote_thread(h)  == 1  then

               -- 用户点击了 OK 按钮

               win32exts.WinExec( "explorer.exe http://my.com", 1 )

      end

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值