Laan's steps..

Feed Rss

asc.jar编译的swf中的一个问题

02.06.2009, flash, by .

首先申明,本人没有用过acs.jar。只是恰好有朋友遇到过swf的相关问题,是由asc编译后引起的。遇到过两次,得出一个东西——asc.jar在编译swf时,喜欢在script中做文章。或将代码植入init函数中,或将多个script中的类加如到一个script中去。我没有研究asc。只能是从结果推过程了。

其中一个问题就是asc合并多个script引起的。这个问题需要一个环境:同程序域加载及存在类覆盖。

比如在Test.swf中有类:

public class Test extends Sprit {}   作为document class.

在Test2.swf中有类:

public class Test extends Sprite {}, 再有类:public class ABCD extends Test {} 作为document class.

这个时候用asc编译Test2.swf。再在Test.swf中加载Test2.swf的话就会出现一个错误:

swf出错框

swf出错框

这里的意思就是在初始化类ABCD的时候,其基类不正确。换句话说,就是没有找到正确的Test类。

为什么会找不到正确的Test类?

这个就比较复杂了。有一个知识点必须知道:在同程序域(Application Domain)下,后加载的类不能覆盖已存在的类。这样的话,其实Test.swf在加载Test2.swf后,由于Test.swf中已经存在一个Test类了,就不会再初始化一个类Test。这时候,在初始化类ABCD时,查找到的类Test应该就是Test.swf中的类。

问题就出在这里。用asc编译出来的Test2.swf将其中的两个类都放在一个scripte中去——用flash编译的swf中是存在两个script,每个script中有一个class trait。我改了该script的init函数的一些指令以引起异常,在调试状态下查看指令操作过程。发现其在初始化类ABCD获取ABCD父类Test时,使用的是getslot指令,后跟一个slotid(本来应该是使用指令getlex,后跟一个multiname index)这个时侯,程序找到的就不是Test.swf中就初始化的Test类。

打个比方,你去买烟,你说要一包芙蓉王。然后店老板就从架上给你取一包。但是你突然指着一个芙蓉王烟包装说:老板,我就要这包烟。getslot指令也是这样,它绕过了AVM(actionscript virtual machine)的代理,直接去取一个类。而实际上,被加载的Test2.swf并没有初始化他自己的Test类。于是就出现了这样的错误。

汗~~终于是说完了。可是自己都觉得没怎么说明白。唉~~~~

最后在说一下解决方案吧。
1:使用flash编译。——只要你懂flash即可
2:更改asc,让它老老实实地编译——如果你懂java而且是熟悉swf及abc结构
3:更改script中init的指令——你得懂swf及abc结构。

我使用的是第三种方法:将getslot指令换乘getlex指令;同时更改后跟索引为相应的类multiname索引。

收工晒网~~~~~~~~~~

asc.jar编译的swf中的一个问题 有1条回应

  1. 看明白了

    编译器在自作聪明

    回复

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>