AS3 load SWF:代码补全

问题

我们载入swf使用类,必须动态获得类,就肯定没法使用代码补全。

// 获得类引用
var AdobeClass:Class = getDefinitionByName("cn.riahome.classes::Adobe") as Class;
// 新建实例
var adobe:* = new AdobeClass();

而且必须要在被载入的SWF中import使用了这些类。


C++

一).静态调用其步骤如下:
1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下;
2.把你的youApp.lib拷到你目标工程(需调用youApp.DLL的工程)目录下;
3.把你的youApp.h(包含输出函数的定义)拷到你目标工程(需调用youApp.DLL的工程)目
录下;
4.打开你的目标工程选中工程,选择Visual C++的Project主菜单的Settings菜单;
5.执行第4步后,VC将会弹出一个对话框,在对话框的多页显示控件中选择Link页。然
后在Object/library modules输入框中输入:youApp.lib
6.选择你的目标工程Head Files加入:youApp.h文件;
7.最后在你目标工程(*.cpp,需要调用DLL中的函数)中包含你的:#include "youApp.h"
注:youApp是你DLL的工程名。

2.动态调用其程序如下:
动态调用时只需做静态调用步骤1.
{
HINSTANCE hDllInst = LoadLibrary("youApp.DLL");
if(hDllInst)
{
typedef DWORD (WINAPI *MYFUNC)(DWORD,DWORD);
MYFUNC youFuntionNameAlias = NULL; // youFuntionNameAlias 函数别名
youFuntionNameAlias = (MYFUNC)GetProcAddress
(hDllInst,"youFuntionName");
// youFuntionName 在DLL中声明的函数名
if(youFuntionNameAlias)
{
youFuntionNameAlias(param1,param2);
}
FreeLibrary(hDllInst);
}
}
采用动态库技术对于升级软件版本更加容易。与静态库(Static Link Library)不同,动态库里面的函数不是执行程序本身的一部分,而是根据执行需要按需载入,其执行代码可以同时在多个程序中共享。
(1)静态调用,也称为隐式调用,由编译系统完成对DLL的加载和应用程序结束时DLL卸载的编码(Windows系统负责对DLL调用次数的计数),调用方式简单,能够满足通常的要求。通常采用的调用方式是把产生动态连接库时产生的.LIB文件加入到应用程序的工程中,想使用DLL中的函数时,只须在源文件中声明一下。 
LIB文件包含了每一个DLL导出函数的符号名和可选择的标识号以及DLL文件名,不含有实际的代码。Lib文件包含的信息进入到生成的应用程序中,被调用的DLL文件会在应用程序加载时同时加载在到内存中。 
(2)动态调用,即显式调用方式,是由编程者用API函数加载和卸载DLL来达到调用DLL的目的,比较复杂,但能更加有效地使用内存,是编制大型应用程序时的重要方式。在Windows系统中,与动态库调用有关的函数包括: 
①LoadLibrary(或MFC 的AfxLoadLibrary),装载动态库。 
②GetProcAddress,获取要引入的函数,将符号名或标识号转换为DLL内部地址。 
③FreeLibrary(或MFC的AfxFreeLibrary),释放动态链接库。


实现方法

AS没有头文件,所以所有的信息包括声明和定义都放一起在代码中。

静态库SWC是直接编译到项目中的,可以获得类信息。

但是以RSL方式使用FLEX,调用FLEX API时却可以获得补齐,并且直接像使用当前项目定义的类一样定义对象。这是因为主工程添加了SWC,指明动态加载并不把SWC静态编译到项目中,过swc获得了类信息。


Flex实际复杂项目中RSL(运行时共享库)的使用方法  介绍了一种模仿RSL的方法获得代码补齐的能力。

和RSL一样,相比直接使用SWC或载入SWF   有个弊端,本来两个的项目的,必须要一个包装SWC为SWF的项目,变为3个项目。


注意事项:主SWF必须使用和SWC所在SWF同样的ApplicationDomain。

            var lc:LoaderContext = new LoaderContext();
            lc.applicationDomain = ApplicationDomain.currentDomain;
            var loader:Loader = new Loader;
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function comp(e:Event):void
            {
                var tc3:TestClass3 = new TestClass3;//swc中的类
                loader.loaderInfo;
                loader.contentLoaderInfo;
            });
            loader.load(new URLRequest("../../Test2/bin-debug/Test2.swf"), lc);

与正常RSL的异同

正常的RSL,文中第二步设置SWC为RSL。

本方法设置swc的连接类型为外部。(PS:FLEX的主工程才能设RSL,AS的只能设置内部外部。)


正常的通过库SWC属性的RSL URL设置对应的SWF,统一位置,自动下载,自动加载,自动保证其他代码在加载后才运行。(估计也是SWC外部包一个SWF。在Preloader帧下载完所有RSL,application.preloader可以看到)

本方法是代码中指定SWF位置加载,人工保证SWF加载完后才使用SWC中的类或资源。


与C++动态库的对比


传统的加载swf,并通过applicationdomain获取类和函数,然后调用;就类似c++动态调用dll内的函数。


C++加载的dll可以自动补全,并且和项目内引用一样直接通过类名定义对象,是因为使用了静态调用,include了头文件声明了类,有对应的无实际函数定义的lib表明函数符号。

这种方法类似静态调用dll。swc就是对应lib和头文件,只不过无法做到没实际函数定义。




文章

以下为Flex实际复杂项目中RSL(运行时共享库)的使用方法 文章内容:

最近连着看了关于RSL的文章,我也说说我现在认识的RSL。
Y.Boy 的 创建自己的RSL
Aedis.Ju 的 动态加载Application

关于AS里的RSL机制以及好处我就不说了,我说说复杂项目中的使用方法。
算是对他们文章的一个补充延伸吧。

我准备说的使用RSL方法,简单的说就是:事情分两步走
(1)flex编写代码的时候:使用设置为不嵌入代码的.swc类库
(2)swf运行的时候:加载包含模块、类、代码、嵌入图片、声音等资源的.swf文件


-------------------
如果你明白我上面的意思,并且在心里想说:我早就是这样做的!
呵呵,那也不需要再往下面看了^-^
---------------------------

<一>使用swf作为类库,常用方法存在的问题
先说说上面两位文章里讲的使用方法(以Y.Boy里的代码为例):
// 获得类引用
var AdobeClass:Class = getDefinitionByName("cn.riahome.classes::Adobe") as Class;
// 新建实例
var adobe:* = new AdobeClass();

简单的项目可以这样做,相对复杂点的项目,比如多个模块开发,这样做就存在问题了:
1 想获得类引用,必须知道并且写正确类的命名空间以及类的类名
(写起来肯定麻烦,并且你拼写错了,编译器也不会报错,只有当运行的时候才会发现)

2 新建实例只能通过new 的方式,某些实现单例的方式就不能用
(如果AdobeClass类是单例,你想获得单例,你写AdobeClass.getInstance()编译器就报错了)  

3 编写代码时没有代码提示,用起来麻烦。

并且还有...此出省略一万五千字


<二>介绍RSL类库的新使用方法

(1) 先获得RSL的源材料:swc和swf1 把你的类、资源等做成swc(或者是别人开发的swc)
最简单的方法是Flex里新建Library project工程

2 新建一个as工程,就一个任务:引入刚才制作好的swc的各个类及资源
发布这个工程,获得swf

(2) 编写项目模块(ActionScript Modules)代码时使用swc

1 在你的项目里,设置项目属性,添加外部库路径,把得到的swc添加进来
Properties -> ActionScript Build Path -> Library path -> add SWC

2 设置swc的连接类型为外部(这是最重要的一步)
点刚才加入的swc前面的'+'号,双击 Link Type: Merged into code 这一项,在弹出的窗口中,将Link Type设置成External。


这样设置swc,你编写代码的时候,你的类,你的资源,就可以像正常导入进来一样,自由使用。
编写的时候也有代码提示,甚至你的代码里都出现了 import cn.riahon.classes.Adobe,类不管是什么随便用,但在发布的时候却不会把这个类以及swc里所有的资源类编译进去。
(发布的时候其实不存在这些类,可以理解成暂时性的“欺骗”了flash)

(3) 运行时加载swf获得类库
主swf运行的时候,使用Loader加载包含类库的 swf Libs文件(第一步得到的那个swf),从而引入libs里的类。
你可以觉定加载的类库所放入的作用域ApplicationDomain,以便在不用的时候可以把加载的类给删除掉。

加载完swf以后(Event.INIT事件后),你就可以使用这个各个类。
如果是模块开发,这个时候可以再去加载使用到这些类的模块。
(总之,一定确保在没有加载完之前千万不要使用)

<完> 我说的使用方法就是这样了

-----------------------------------
说明:以上绝非我自己发现的方法,好多“仙人”都已经这样用了...
我是怎么知道的?翻看《ActionScript3 编程精髓》的第767页以及同事 张成亮 给我讲的。



我要啦免费统计
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值