Flash C++ Compiler (FlasCC) 会根据您针对 Adobe Flash Player 和 Adobe AIR 编译 C/C++ 代码时可使用的 GCC,提供完善的 C/C++ 开发环境。 借助 flascc,您几乎可以将任何现有的 C/C++ 代码移植到 Web。本文介绍了一些相关提示和技巧,从而帮助您顺利开始使用 flascc。
GDB 调试提示与基于 GCC 的绝大部分工具链类似,flascc 运用 GDB 作为调试程序。 它提供了定制版本的 GDB,用以调试 Flash Player 内运行的 flascc 编译的 C/C++ 代码。设置 FLASCC_GDB_RUNTIME 环境变量要执行 GDB,您必须定义包含单机调试版本 Flash Player 或安装调试版本 Flash Player 的 Web 浏览器的完全限定路径的 FLASCC_GDB_RUNTIME环境变量。 如果该路径包含空格,请使用双引号 (Windows) 或运用反斜杠代替空格 (Mac)。例如: - 在 Windows 上:
- FLASCC_GDB_RUNTIME="/cygdrive/c/Program Files (x86)/Mozilla Firefox/firefox.exe"
复制代码 - 在 Mac OS X 上:
- FLASCC_GDB_RUNTIME= export
- FLASCC_GDB_RUNTIME=/Users/flex/runtimes/player/11.3/mac/Flash\
- Player\ Debugger.app
复制代码 在 Firefox 中使用 GDB如果您使用 Firefox,可能希望延长或禁用插件挂起检测时间,从而避免浏览器在调试期间过早终止 SWF。 有关此操作方法的详细信息,请参阅MozillaZine 上的此主题相关文章。 将 GDB 连接到远程站点上托管的 SWF如果您的 flascc 应用程序在远程站点(例如,临时服务器)上运行,请设置 FLASCC_GDB_RUNTIME 环境变量指向您的浏览器(如上所述),然后在启动远程应用程序时,将远程应用程序的 URL 传递到 GDB,例如:
- gdb [url]www.mysite.com/games/mygame.html[/url]
复制代码
- 使用 GDB 调试 SWC编译 SWC 时,您可以指定一个命名空间。 这样,当您调试该 SWC 时,需要告知 GDB 您要对哪个命名空间使用 setas3namespace 命令。 您可以在每个会话中仅调试一个 SWC。 有关详细信息,请参阅本地 flascc 安装目录下docs/Reference.html 中的 GDB 部分或在线 参考资料。
- 使用 GDB 调用命令使用 GDB 进行调试时,您可以使用调用命令在代码中调用函数。 这可以是您感兴趣的任意函数,或者也可以是专为进行调试添加的函数。例如: (gdb) call dumpValues()
- 在 GDB 中重新运行 SWF(并忽略相关警告)当您在 GDB 中重新运行 SWF 时,可能会看到如下警告:
警告: 暂时为卸载共享库禁用断点 "remote:0.elf"
您可以放心地忽略这些警告。
下面是一个在 GDB 中运行和重新运行 SWF 的示例:- <path>/sdk/usr/bin/gdb call.swf
- GNU gdb (GDB) 7.3 Copyright (C) 2011 Free Software Foundation, Inc.
- License GPLv3+: GNU GPL version 3 or later <[url]http://gnu.org/licenses/gpl.html>[/url]
- This is free software: you are free to change and redistribute it.
- There is NO WARRANTY, to the extent permitted by law. Type "show copying"
- and "show warranty" for details.
- This GDB was configured as "--host=x86_64-apple-darwin10 --target=avm2-elf".
- For bug reporting instructions, please see:
- <[url]http://www.gnu.org/software/gdb/bugs/>...[/url]
- (gdb) b main
- No symbol table is loaded. Use the "file" command.
- Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 1 (main) pending.
- (gdb) r
- Starting program: call.swf
- 0xdddddddd in ?? ()
- Breakpoint 1, 0xf0000247 in main (argc=0, argv=0x200ff0) at call.c:66
- 66 int s = 2;
- (gdb) r
- The program being debugged has been started already.
- Start it from the beginning? (y or n) y
- warning: Temporarily disabling breakpoints for unloaded shared library "remote:0.elf"
- Starting program: call.swf
- 0xdddddddd in ?? ()
- Breakpoint 1, 0xf0000247 in main (argc=0, argv=0x200ff0) at call.c:66
- 66 int s = 2;
- (gdb)
复制代码 忽略 "No symbol table is loaded...." 消息在某些情况下,当您运行 GDB 时,将会看到以下消息:- No symbol table is loaded.... pending on future shared library load
复制代码 您可以放心地忽略这条警告。使用monitor eval <longLocalVariableString>查看 GDB 中的长 String 值如果 String 长度超过 80 个字符,则 GDB 无法在常规局部变量列表中显示 ActionScript 3 String。 要查看这些 String 值,请使用 monitor eval 命令。例如, monitor eval myLongVariable 可用于显示 String 值,并且不受长度限制。
优化提示
完成调试准备优化时,请考虑使用以下提示。生成全面优化的应用程序默认情况下,flascc 版本的 GCC 会生成 ActionScript ByteCode (ABC)。 当需要快速完成编译时,则大多数开发周期使用这种方法足矣。 不过,为了实行全面优化,调用 GCC 时,请使用 -emit-llvm 或 -O4 选项。 这些选项会生成 LLVM 字节码,从而创建 Link Time Optimized (LTO) 版本。 虽然使用这些交换机执行编译花费的时间较长,但您将能够获得全面优化的最终版本,所有内容均已编译为 LLVM 字节码。 例如,以下代码行可以创建全面优化的版本:- gcc test.c -emit-llvm -c -o test.o
- gcc test.c -O4 -c -o test.o
- gcc test.c -emit-llvm -emit-swf -o test.swf
- gcc test.c -O4 -emit-swf -o test.swf
复制代码 使用 GCC 生成 SWC当使用 GCC 生成 SWC 时,您必须使用 -emit-swc= 选项指定 AS3 包名称,其中将包含生成的代码及内部 flascc 样板文件代码。 这样,您便能够将 flascc 生成的多个 SWC 链接为一个 SWF,并且不会产生任何函数或类冲突。 下面的例子源自 /tutorials/05_SWC/makefile:- "$(FLASCC)/usr/bin/g++" -O4 MurmurHash3.cpp as3api.cpp main.cpp
- -emit-swc=sample.MurmurHash -o MurmurHash.swc
复制代码 有关详细信息,请参阅本地 flascc 安装目录下 docs/Reference.html 中的“构建 SWC”部分。优化 SWC 和 SWF 大小虽然 GCC 包含的许多选项可以最大限度地缩小输出数据规模,但以下几种选项是最常用的技巧:
- 使用 GCC -O4 选项生成 LLVM 字节码,并创建经过全面优化的版本。
- 使用导出文件自定义版本中包含的数据。 例如,参见 /tutorials/12_Stage3D/exports.txt.
- 试用 llvm 提供的各种优化选项(如 –Os)
针对较旧的 SWFSWF 版本决定可供使用的 AIR 和 Flash Player API 版本。 例如,SWF 17 等效于 AIR 3.4 和 Flash Player 11.4;如果指定 SWF 16,您的应用程序将仅有权访问 AIR 3.3 和 Flash Player 11.3 API。 如由于某些原因,您希望使用较旧的 SWF 版本,请使用 GCC -swf-version=选项(当前的默认设置为 SWF 17 版本,因此请将其更改为 SWF 16 版本,您需要指定以下设置:
-swf-version=16
有关 SWF 版本与 Flash Player 版本相互映射的详细信息,请参阅创建扩展描述符文件。对 Flash 类使用 C++ 包装器Flascc 提供了一组头文件,用于包装 Flash 顶级类(例如,Number 和 Array)以及 Flash 类库(例如,flash.display.Stage 和 flash.display.Stage3D)。 这些包装器有权访问对应的 ActionScript 类的所有方法、属性和事件。 有关详细信息,请参阅 flascc 安装目录下docs/Reference.html 中的“C/C++ 与 ActionScript 交互操作”部分。tutorials/12_Stage3D/stage3d.cpp 中也使用这些包装器。自定义默认预加载程序Flascc 应用程序会自动纳入一个简单的预加载程序,并将其显示为 SWF 负载。 您可以创建自定义预加载程序,将其用于 flascc 应用程序。 《flascc 参考指南》中对此做出了说明,您可以在 flascc 的 /docs 安装目录下下载本指南。调整 Java 内存分配虽然强烈建议您对 flascc 使用 64 位 Java,但有些开发商已经能够对某些小型应用程序使用 32 位 Java。 在这种情况下,如果计算机的内存有限,您可能需要降低 Java 堆规范(默认设置为 –jvmopt="-Xmx1500m"),缩小其数值,例如,缩小为–jvmopt="-Xmx256m"。 您可以在生成文件中调用 GCC 时执行此操作。例如:- gcc -jvmopt="-Xmx256M" hello.c -o hello.exe
复制代码 相反,如果您运行 64 位 Java 且您的计算机具有可用内存,您可能希望增加 Java 堆大小。64 位 Java 可以从 Oracle 软件下载 页面获取。
更多提示
下面是一些有关 flascc 使用的其他提示。将 SWC 文件中的类用作 Console当链接到 SWC 后,您必须指定即将用作 Console 的对象。
您应当先调用 CModule.vfs.setConsole(this);,然后再调用 ActionScript 文件中的 initLib(),同时还要纳入一个 write() 实现,如下所示:- public function write(fd:int, buf:int, nbyte:int, errno_ptr:int):int
- {
- var str:String = CModule.readString(buf, nbyte);
- trace(str); // or display this string in a textfield somewhere?
- return nbyte;
- }
复制代码 有关其他示例,请参阅 04_Animation 教程中的 Console.as。自定义 SWF 维度要指定 SWF 维度,请将 -swf-size=widthxheight标志传递给 GCC;例如:-swf-size=200x200.定义 import,以便在函数调用中使用 Context3d要定义 import(以便在函数调用中使用 Context3D),请使用 as3import 注释。 下面的示例代码段源自/tutorials/Example_BulletPhysicsLibrary/bullet.i:- void positionAndRotateMesh() __attribute__((used,
- annotate("as3sig:public function positionAndRotateMesh(mesh:*,
- rigidBody:*):void"),
- annotate("as3package:org.bulletphysics"),
- annotate("as3import:flash.geom.Vector3D")));
复制代码 防止按值返回结构和对象的函数的包装器发生内存泄露当使用 SWIG 编译器从 C/C++ 头文件创建 SWC 时,请注意以下几点:- 默认情况下,按值返回结构和对象的函数的包装器会泄露内存。 SWIG 无法自行了解何时应当释放这些值,因此,我们期望调用包装器的代码能够保证在适当的时间释放返回的值。
- Flascc 不包含任何 std::string 标准 Typemap,也不包含任何 C++ 标准库类。 正因如此,在包装器中std::string 或相似类的许多应用可能无法按预期正常运行,您将需要编写应用程序特定 Typemap 达成所需的行为。
使用 as3wig 创建 C++ 接口您可以使用 flascc AS3 Wrapper Interface Generator (as3wig) 为现有的 ActionScript 3 ActionScript ByteCode (ABC) 创建 C++ 库接口。 举例来说,请参阅本地安装的 /tutorials/12_Stage3D/makefile,特别是以下代码行:- sdk/usr/lib/as3wig.jar -i AGAL.abc -o AGAL
复制代码 创建自定义Console 实现当加载 SWF 时,Console 类是需要创建和执行的首个类。 它是一个 ActionScript 类,用于控制初始化 flascc 编译代码的时间和方式。 另外,底层 flascc POSIX 实现也用它作为处理各种标准输入、输出和错误终端流的读写请求的对象。 在某些情况下,您将希望创建自定义 Console 实现。 例如,虽然您可以使用 Flash++.h 中所含的 C++ 包装器与所有 Flash API 进行交互,您可能更喜欢在 Console 实现过程中单纯使用 ActionScript 3。 有关 Console 类的信息,请参阅 flascc 安装目录下 /docs/apidocs/index.html 中的 ActionScript API 文档。 有关完整信息,请参阅 flascc 安装目录下的 /docs/Reference.html。不要使用 fsync()Flascc 不支持 fsync()。 相反,关闭该文件,即可提交您的更改。使用 CModule.startBackground() 和 CModule.startAsync()com.adobe.flascc.CModule ActionScript 类包含读写 domainMemory 的便捷函数。 同时,它还负责管理所有 flascc 特定的全局状态(例如,VFS 和 POSIX 接口实现)。 在其他方法中,请注意以下方法之间的区别:- startAsync()– 调用 libc __start1函数,反过来导致执行 main()。
- startBackground()– 创建后台 Worker,然后在该 Worker 内运行 libc 函数 __start1。 此方法需要使用 SWF 18 (Flash Player 11.5) 版或更高版本。
有关 CModule 类的信息,请参阅 flascc 安装目录下 /docs/apidocs/index.html中的 ActionScript API 文档。
|