Vitesse2DLL文档

来源:互联网 发布:淘宝网药品 编辑:程序博客网 时间:2024/04/30 04:36

Vitesse2Dll可将TribonVitesse程序的py文件编译成DLL文件发布。其优点是反编译难度比较大,程序执行速度快。下文介绍了程序的使用方法,及在编码过程中需要注意的事项,此外程序部署和更新也做了说明。

 

一、Vitesse2Dll程序使用说明

 

1. 计算机必须连接互联网。

2. 将Vitesse2DLL解压,解压位置请勿使用带空格的路径和中文路径。

3.将要编译的vitesse程序拷贝到某个路径,路径也不能使用带空格路径和中文路径,Win7以上操作系统,请勿放置到C盘。Vitesse程序文件名不能包含中文。

image

4. 开始-运行输入cmd回车。

5. 输入vitesse2dll.exe路径,参数为vitesse程序文件夹路径。

6. 程序打包py文件并上传服务器,此时等待服务器编译。

image

7. 编译完成程序自动下载将编译好的dll文件解压到py文件的路径中。

image

8. 显示Server down! Please trylater.可能是因为服务器没有响应,也可能因为编译时间太长。请等一段时间,再试一次上面的命令。

9. 由于程序有上传下载行为,360杀毒软件会误报病毒,如果不放心,可以使用公共计算机,例如网吧机器或者开个虚拟机操作。

10. 一次上传最大文件数50个,每个文件最大100K。

 

二、 编码注意事项

 

1. PY文件编码

请按照如下一种方式来处理中文问题,避免编译错误,也能适应所有开发工具。就是在使用了中文字符的PY文件开头第一行添加下面这行代码:

# -*- coding: cp936 -*- #

cp936是Python自带IDE的默认编码,也是Tribon能够识别的中文字符的编码格式。

使用BoaConstruction创建的wxApp和wxFrame文件默认是不需要添加编码的,因为boa将中文都处理为编码后的格式。如下所示,界面中添加的中文已经转码:

self.comboBoxDatabase.SetLabel('\xd6\xd0\xce\xc4')

这样的文件可以直接编译DLL不会出错,问题是在代码中无法通过肉眼看到中文内容。如果使用其他IDE修改该文件添加了中文,一样无法编译通过。此问题大家可酌情处理。

 

2. 空格和Tab

测试中发现PY文件中空格和Tab键混用编译会出错。按照编码规范,使用四个空格代替Tab键,现在所有的PythonIDE都能够设置,请大家遵守此开发规则。

 

3. 使用 import *

编译DLL文件要求PY文件中只有文件头可以使用import *,但是在PY文件的函数里面不能使用。例如下面这样是可以的:

from foo import *

class A:

    defB(self):

       pass

但是下面这样不行:

def B(self):

    from fooimport *

wxPython都是在文件头位置import *,编译没有问题。新版本的wxPython都不使用import*了,因为这不是个很好的编码习惯。对于我们的类来说,正常使用import并用命名空间调用属性或者方法就可以了。

正常的import模块不受位置影响,都能编译通过。

 

4. 静态检查

PY编译成DLL文件,是将动态代码转化成静态代码。故此原来动态代码允许的语句,编译的时候会出错。例如函数中调用了没有import的模块,下面这段代码,函数中的os模块没有import,保存成py文件是可以编译成pyc文件的,因为foo函数并没有调用:

def foo():

    printos.getcwd()

但是这个PY文件却不能编译成DLL文件,必须在函数上面import os。

类似的问题还有在if语句中调用了不存在的函数:

If a > 0:

   NotExist()

或者函数中出现了没有定义的变量:

def A(a):

    for i inb:

       print i

以上情况都可以将py文件编译成pyc文件,但是编译成DLL会出错。相当于对动态的python文件进行了静态检查,对我们代码的可靠性起到了增强作用。

 

5. 编译器bug

尽管编译DLL进行测试的代码量不是很大,还是遇到了由于编译器Bug引起的编译失败。我遇到的问题是:

if:

   

elif:

   

else:

    print“not exist!”

错误提示在最后一行有错误。我取消print语句后编译通过。在else上面添加print编译也能通过。如果调整代码可以绕开编译器的bug,还是可以的接受的。

 

6. 语法兼容性

Python语法eval不适用,编译DLL文件后出错。eval会计算字符串形式的Python表达式,并返回结果的值。例如:

>>> eval_r('float(3+4)')

7.0

动态添加类的属性或成员函数不适用,编译DLL文件后出错。

>>> def func(a,b):

... print a,b

>>> class Foo(object):

... pass

>>> foo = Foo()

>>> Foo.func = func

>>> foo.func(4)

<__main__.Foo object at 0x3f79db0> 4

能编译不等于能运行,语法兼容性问题,在py文件、pyc文件运行时没有错误,只有编译为DLL才会出错。

 

DLL程序部署

 

Vitesse程序编译为DLL之后,不能在VitesseToolbar直接运行。需要写一个py文件导入执行,例如我在性能测试代码里面,就带了一个runTest.py文件用来在VitesseToolbar中执行DLL。但是DLL可以在Tribon快捷方式中直接调用,只要保证run()函数入口,所以不必为每个DLL文件都编写导入程序。生产环境放一堆DLL有一个引用文件即可,开发环境应该全部是py文件,否则没法调试程序。

推荐大家采用下面这种方式在生产环境部署VitesseDLL程序:


1.    编写一个START.py文件,文件内容如下:

START.py

defrun():

  sbPython =r"d:/test"

  kpu= KcsPythonUtil.PythonUtil()

  kpu.AppendPythonPath(sbPython)

  name ="Toolbar"

  ds =__import__(name)

  ds.run()

if __name__ =='__main__':

run()


2.    在触发器trig_draft_init.py中添加如下红色部分代码:

trig_draft_init.py

importSTART

#

# All user interface changes mustbe done in the post-trigger.

# When the pre-trigger fires,Windows has not yet created the

# necessary objects we dependon.

#

def post(*args):

   START.run()

   AddVitesseAddIns()

   return kcs_util.trigger_ok()


START.py定义了程序的部署位置,导入了工具条或菜单。sbPython是程序的部署位置。Toolbar.py是你真正的程序代码,负责导入快捷方式、菜单,可以编译成DLL文件。trig_draft_init.pySTART.py都不需要编译成DLL文件。

有点儿绕,但是一次做好以后就不用动了,当然依然不能忘了SB_PYTHONSBB_TRIGDIR两个Tribon环境变量的正确设置。这样做的好处是:

l trig_draft_init.py简洁清晰,便于不同公司的二次开发程序并存,每个公司只需要将自己的模块导入执行。

l START.py除了导入DLL文件,可以增加pythonpath的设置,自定义程序的部署位置。用户可以自己配置。

(感谢QQ网友:“不知道”对于触发器编译问题的纠正。)


四、 更新策略


DLL文件调用与pyc不同,DLL文件是独占的。如果有用户调用某个DLL文件,该DLL无法删除。为了能够实时更新代码,可采用的方式是对旧DLL文件改名,然后拷贝新文件到共享位置。用户重新调用DLL文件时候会调用新的DLL文件,旧文件被用户释放后就可以删除了。如果用户不退出。改名后的文件始终无法删除。更新模块后,需将目前打开的所有Tribon模块关闭后,再启动新程序才能好用。

ReleaseDLLs工具可实现DLL文件的自动更新,对于无法删除的旧DLL文件,自动更名为后缀.old的文件。新文件即可部署,待旧文件释放再手动删除。新启动的Tribon模块自动调用新文件。
使用方法是在cmd窗口中输入命令:
ReleaseDLLs.exe DLL源路径 DLL目标路径
DLL源路径是要部署的DLL文件所在的路径,DLL目标路径是要更新的DLL文件所在的路径。

image
如上图所示,程序会将d:/py/test下的DLL文件更新到d:/py/dst文件夹中。只要保证源路径与目标路径下子文件夹的结构相同,子文件夹的DLL文件可一次实现更新。例如test和dst文件夹都有trigger目录,使用上述命令可实现trigger子文件夹的更新。

 

五、 性能测试

 

我直接在网上找了一段Python连接字符串的性能测试源代码,测试程序的本意是测试Python不同连接字符串方法的性能,我在Tribon中测试了一下,足以说明问题。PYC文件与DLL文件测试结果如下:

PYC文件

short items test:

'use % to join' run 1000000 times, spent 5.250000 seconds

'use str.join ' run 1000000 times, spent 5.062000 seconds

'use + ' run 1000000 times, spent 4.469000 seconds

'use += ' run 1000000 times, spent 7.062000 seconds

-----

long items test:

'use % to join' run 1000000 times, spent 10.704000 seconds

'use str.join ' run 1000000 times, spent 6.828000 seconds

'use + ' run 1000000 times, spent 9.797000 seconds

'use += ' run 1000000 times, spent 13.578000 seconds

DLL文件

short items test:

'use % to join' run 1000000 times, spent 2.906000 seconds

'use str.join ' run 1000000 times, spent 2.969000 seconds

'use + ' run 1000000 times, spent 2.313000 seconds

'use += ' run 1000000 times, spent 3.250000 seconds

-----

long items test:

'use % to join' run 1000000 times, spent 8.172000 seconds

'use str.join ' run 1000000 times, spent 4.484000 seconds

'use + ' run 1000000 times, spent 7.359000 seconds

'use += ' run 1000000 times, spent 9.703000 seconds

从测试结果上看,DLL文件比PYC文件有性能提升,但是性能提升不是线性增长的。在实际Vitesse程序中,我们一般不会处理百万级的字符串操作,最主要的是程序性能瓶颈在TribonAPI上,所以感觉性能提升也不明显。但些许的提升,放在数百人的生产环境中,每天被无数次调用,价值就体现出来了。

为了使两次测试状态尽量接近,我在VitesseToolbar里面先用runTest.py引导test.pyc获得测试结果,关闭Tribon模块重新启动,同样用runTest.py引导test.dll获得第二次结果。如果你的测试结果与我相悖,请先考虑是否测试环境发生了变化。

0 0