PyPb系列-技术实现原理(一)-python中使用systemlibray

8 篇文章 0 订阅

总体目标的实现,首先通过python将sra文件编译成exe,Popen启动exe,调用写好的动态库文件函数,调用test.py中的代码。

先看一下实现的效果,testHello.py的代码

from PyPB import RUN,messagebox

def main():
    messagebox("提示","你好,PB!")
RUN(__name__,__file__,main)

那我们是如何实现,在python中调用pb的messagebox的呢,这里就必须要用systemlibray了。基础部分就不介绍了,深入了解,百度哈。还有一个基础就是需要将python34源码编译成dll,我们把pbvm**.dll的handle注入到sys.pbvm中,程序启动时的_obThis等注入到sys.pb_app中。通过ctypes获取到对应的值

__obThis = ctypes.c_void_p ( sys.pb_app[0] )
__pGroup = ctypes.c_void_p ( sys.pb_app[1] )
__appinst = ctypes.c_void_p ( sys.pb_app[2] )
pbvm = ctypes.WinDLL("pbvm", handle = sys.pbvm)

定义OB_DATA,OB_DATA_INFO,RT_CALL_INFO,OB_CLASS_HNDL等结构体对象。

OB_CONST_REF =ctypes.c_ulong
class OB_VALUE(ctypes.Union):
    _pack_ = 1
    _fields_ = [
        ('int_val', ctypes.c_short),   # 			SHORT				int_val;		 	// Integer value
        ('fl_val', ctypes.c_float),  # 			FLOAT				fl_val;				// Float value
        ('pchar', ctypes.c_char_p),
        ('ptr', ctypes.c_void_p),    # 			PVOID				ptr;			 	// Ptr to value
        ('const_ref', OB_CONST_REF), # 			OB_CONST_REF		const_ref;			// Constant value
        ('ob_inst', ctypes.c_void_p),# 			PVOID				ob_inst;			// There for compatibility, ptr should be used instead
        ('id', ctypes.c_ushort),     # 			USHORT				id;					// Id value
        ('uint_val', ctypes.c_ushort),# 			USHORT				uint_val;			// Unsigned integer
        ('long_val', ctypes.c_long),  # 			LONG				long_val;			// Long integer
        ('ulong_val', ctypes.c_ulong), # 			ULONG				ulong_val;			// Unsigned Long integer
        ('byte_val', ctypes.c_byte),  # 			BYTE				byte_val;			// Byte value
    ]
class OB_DATA(ctypes.Structure):
    _fields_ = [
        ('val' , OB_VALUE),
        ('info' , OB_INFO_FLAGS ),
        ('type' , OB_CLASS_ID),
    ]
POBDATA = ctypes.POINTER(OB_DATA)

 函数调用代码

def rtRoutineSearch(inst, func_name:str, p_ob_data:POBDATA, args_len , function_or_event = 0)-> tuple :
    rtCallInfo = RT_CALL_INFO()
    rtCallInfo.enCallType = 2
    if not inst:
        och,_ = ob_global_reference("systemfunctions")
        rtCallInfo.rtClassInfo.obClassHndl.class_id = och.class_id
        rtCallInfo.rtClassInfo.obClassHndl.group_hndl = och.group_hndl
    else:
        rtCallInfo.rtClassInfo.obInst = inst
        rtCallInfo.rtClassInfo.obClassHndl.class_id = ob_get_obinst_system_class(inst) 
        rtCallInfo.rtClassInfo.obClassHndl.group_hndl = ob_get_obinst_group_hndl(inst)
    rtCallInfo.bDontTerminateRuntime = True
    ovid=ctypes.pointer(ctypes.c_ushort())
    pbvm.rtRoutineSearch.argtypes = (ctypes.c_void_p, RT_CALL_INFO,ctypes.c_char_p,ctypes.POINTER( OB_DATA ),
                ctypes.c_uint,ctypes.c_int , ctypes.POINTER(ctypes.c_ushort))
    p_func_name = ctypes.c_char_p(func_name.encode("GBK"))
    #print("rtRoutineSearch的参数", p_ob_data)
    find = pbvm.rtRoutineSearch(__obThis, rtCallInfo,
            p_func_name, p_ob_data, args_len, function_or_event, ovid)
    return find == 1, ovid.contents.value, rtCallInfo
def rtRoutineExec(rtCallInfo, pobdata:POBDATA, argslen,ovid,routtype=0)->tuple:
    '''
    调用pb函数,必须先调用rtRoutineSearch方法
    '''
    pbvm.rtRoutineExec.argtypes = (ctypes.c_void_p, RT_CALL_INFO,
        ctypes.POINTER( OB_DATA ),ctypes.c_uint, ctypes.c_ushort,ctypes.c_int,ctypes.c_bool )
    hrt = pbvm.rtRoutineExec(__obThis, rtCallInfo, pobdata, argslen, ovid, routtype, True)
    if hrt != 0 : return False,None
    pbvm.rtReturnValGet.restype = ctypes.POINTER( OB_DATA )
    pob = pbvm.rtReturnValGet(__obThis)
    return hrt==0, pob.contents

调用示例

from PyPB import RUN,messagebox,rtRoutineSearch,rtRoutineExec,OB_DATA,POBDATA,ob_set_data_string,INT_TYPE
import ctypes
def main():
    #messagebox("提示","你好,PB!")
    
    pobdata = ctypes.cast( (OB_DATA*2)(),POBDATA)
    ob_set_data_string(pobdata[0],"提示")
    ob_set_data_string(pobdata[1],"你好,PyPB")
    ok,vid,rtCallInfo = rtRoutineSearch(None,"messagebox",pobdata,2)
    if ok:
        ok,rtObdata = rtRoutineExec(rtCallInfo,pobdata,2,vid)
        print("数据类型",rtObdata.type==INT_TYPE)# 输出 数据类型 True
        print("返回值",rtObdata.val.int_val)# 输出      返回值 1
RUN(__name__,__file__,main)
ff213141-26e2-4c64-9724-e841f33aa1b2

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值