Macromedia Air - 2017 User Manual

Developing Native Extensions for ADOBE
®
AIR
®

Legal notices

Legal notices
Last updated 1/27/2017

Contents

Chapter 1: Introducing native extensions for Adobe AIR
About native extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Native extensions architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Task overview to create a native extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Chapter 2: Coding the ActionScript side
Declare the public interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Check for native extension support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Create an ExtensionContext instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Call a native function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Listen for events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Dispose of an ExtensionContext instance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Access the native extension’s directory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Identify the calling application from a native extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Native extension backward compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
iii
Chapter 3: Coding the native side with C
Extension initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Extension context initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Context-specfic data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Extension context finalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Extension finalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Extension functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Dispatching asynchronous events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
The FREObject type . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Working with ActionScript primitive types and objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Threads and native extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Chapter 4: Coding the native side with Java
Implementing the FREExtension interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Extending the FREContext class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Implementing the FREFunction interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Dispatching asynchronous events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Accessing ActionScript objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Working with ActionScript primitive types and objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Threads and native extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Chapter 5: Packaging a native extension
Building the ActionScript library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . of a native extension 39
Creating a signed certificate for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a native extension 40
Creating the extension descriptor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . file 41
Building the native library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Creating the native extension package . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Including resources in your native extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .package 51
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Contents
Chapter 6: Building and installing native extensions for AIR for TV
Overview of tasks in developing AIR for TV extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
AIR for TV extension examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
The device-bundled extension and the stub extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Check for extension support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Building an AIR for TV native extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Adding resources to your AIR for TV native extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Distributing the AIR for TV native extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
Running an AIR application on an AIR for TV device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Chapter 7: Native extension descriptor files
The extension descriptor file structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Native extension descriptor elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Chapter 8: Native C API Reference
Typedefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Structure typedefs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Functions you implement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
Functions you use . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
iv
Chapter 9: Android Java API Reference
Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
Last updated 1/27/2017

Chapter 1: Introducing native extensions for Adobe AIR

Native Extensions for Adobe AIR are code libraries that contain native code wrapped with an ActionScript API. You can use native extensions in an AIR application to access platform features not supported by AIR, to benefit from native-code-level performance for critical algorithms, and to reuse existing native code libraries.

About native extensions

What is Adobe AIR?

Adobe® AIR® is a cross-operating system runtime that allows content developers to build rich Internet applications (RIAs). The developers can deploy the RIAs to the desktop, mobile devices, and digital home devices. AIR applications can be built using Adobe® Flex® and Adobe® Flash® (SWF-based) and also with HTML, JavaScript, and Ajax (HTML­based). For more information about the Adobe Flash Platform tools that you can use to build AIR applications, see
Adobe Flash Platform tools for AIR development in Building Adobe AIR Applications.
1

What is Adobe ActionScript?

SWF-based AIR applications can use Adobe ActionScript® 3.0. ActionScript 3.0 is an object-oriented language that can add interactivity and data-handling to RIAs. For more information about the language, see and ActionScript 3.0 Developer's Guide.
ActionScript provides many built-in classes. For example, MovieClip, Array, and NetConnection are built-in ActionScript classes. Additionally, a content developer can create application-specific classes. Sometimes an application-specific class derives from a built-in class.
The runtime executes the code in ActionScript classes. The runtime also executes JavaScript code that is used in HTML-based applications.
Learning ActionScript 3.0

What is a native extension?

A native extension is a combination of:
ActionScript classes.
Native code. Native code is defined here as code that executes outside the runtime. For example, code that you write
in C is native code. On some platforms, Java code is supported in extensions. For the purpose of this documentation, this is also considered “native” code.
Reasons to write a native extension include the following:
A native code implementation provides access to device-specific features. These device-specific features are not
available in the built-in ActionScript classes, and are not possible to implement in application-specific ActionScript classes. The native code implementation can provide such functionality because it has access to device-specific hardware and software.
A native code implementation can sometimes be faster than an implementation that uses only ActionScript.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Introducing native extensions for Adobe AIR
A native code implementation allows you to reuse existing code.
For example, you could create a native extension that allows an application to do the following:
make a mobile device vibrate.
interact with device-specific libraries and features.
When you have finished your ActionScript and native implementations, you package your extension. Then, an AIR application developer can use the package to call your extension’s ActionScript APIs to execute device-specific functionality. The extension runs in the same process as the AIR application.

Native extensions versus the NativeProcess ActionScript class

ActionScript 3.0 provides a NativeProcess class. This class lets an AIR application execute native processes on the host operating system. This capability is similar to native extensions, which provide access to device-specific features and libraries. When deciding on using the NativeProcess class versus creating a native extension, consider the following:
Only the extendedDesktop AIR profile supports the NativeProcess class. Therefore, for applications with the AIR
profiles
Native extension developers often provide native implementations for various platforms, but the ActionScript API
they provide is typically the same across platforms. When using the NativeProcess class, ActionScript code to start the native process can vary among the different platforms.
The NativeProcess class starts a separate process, whereas a native extension runs in the same process as the AIR
application. Therefore, if you are concerned about code crashing, using the NativeProcess class is safer. However, the separate process means that you possibly have interprocess communication handling to implement.
mobileDevice and extendedMobileDevice, native extensions are the only choice.
2

Native extensions versus ActionScript class libraries (SWC files)

The most important difference between a native extension and a SWC file is that the SWC file contains no native code. Therefore, if you determine that you can accomplish your goal without native code, use a SWC file rather than a native extension.
More Help topics
About SWC files

Supported devices

You can create native extensions for the following devices:
Android devices, starting with AIR 3 and Android 2.2.
iOS devices, starting with AIR 3 and iOS 4.0
iOS Simulator, starting with AIR 3.3
Blackberry PlayBook, starting with AIR 2.7
Windows desktop devices that support AIR 3.0
Mac OS X desktop devices that support AIR 3.0
An extension can target multiple platforms. For more information, see “Targeting multiple platforms” on page 5.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Introducing native extensions for Adobe AIR

Supported device profiles

The following AIR profiles support native extensions:
extendedDesktop, starting in AIR 3.0
mobileDevice, starting in AIR 3.0
More Help topics
AIR profile support

Native extensions architecture

Architecture overview

AIR allows an extension to do the following:
Call functions implemented in native code from ActionScript.
Share data between ActionScript and the native code.
Dispatch events from the native code to ActionScript.
When you create a native extension, you provide the following:
3
ActionScript extension classes that you define. These ActionScript classes use the built-in ActionScript APIs that
allow access to and data exchange with native code.
A native code implementation. The native code uses native code APIs that allow access to and data exchange with
your ActionScript extension classes.
Resources, such as images, that the ActionScript extension class or the native code uses.
Your native extension can target multiple platforms. When it does, you can provide a different set of ActionScript extension classes and a different native code implementation for each target platform. For more information, see “Targeting multiple platforms” on page 5.
The following illustration shows the interactions between the native extension, the AIR runtime, and the device.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Introducing native extensions for Adobe AIR
AIR application
Extension resources
ActionScript
extension classes
Device operating system and libraries
Native extension architecture
(for example, images)
Native
implementation
extension
AIR runtime

Native code programming languages

Adobe AIR provides native code APIs that your native code implementation uses for interacting with the ActionScript extension classes. These APIs are available in:
4
the C programming language.
Java
Your native code implementation uses either the C APIs or the Java APIs, but not both, for interacting with the ActionScript extension classes. However, the rest of your native code implementation does not have to exclusively use the same language as the APIs. For example, a developer using the C API can also use:
C++
Objective-C
assembler code to take advantage of highly optimized routines
The following table shows which extension API to use depending on the target device:
Device Native code API to use
Android devices Java API with the Android SDK.
C API with the Android NDK.
iOS devices C API
Blackberry PlayBook C API
Windows desktop devices C API
Mac OS X desktop devices C API
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Introducing native extensions for Adobe AIR

Targeting multiple platforms

A native extension often targets multiple platforms. For example, an extension can target devices running iOS and devices running Android. In this case, your ActionScript class implementation and your native code implementation, including the native code language, can vary based on the target platform.
A best practice is for your ActionScript extension classes to provide the same ActionScript public interfaces regardless of their implementation. By keeping the public interfaces the same, you have a true cross-platform native extension. If the ActionScript public interfaces are the same, but the ActionScript implementation is different, you create a different ActionScript library for each platform.
You can also create extensions that do not have a native code implementation for some target platforms. Such an extension is useful in the following situations:
When only some target platforms support a native implementation of the desired functionality.
An extension can use a native implementation on those platforms, but use an ActionScript-only implementation on other platforms. For example, consider one platform that provides a specialized mechanism for communication between computer processes. The extension for that platform has a native implementation. The same extension for another platform is ActionScript-only, using ActionScript Socket classes.
When application developers use the extension, they can write one application without knowing how the extension is implemented on the different target platforms.
5
When testing an extension.
Consider a native extension that uses a specific feature of a mobile device. You can create an ActionScript-only extension for the desktop. Then, an application developer can use the desktop extension for simulation testing during development before testing on the real target device. Similarly, as an extension developer, you can test the ActionScript side of your extension before involving your native code implementation.
When you publish an extension, you specify the target platforms in an extension descriptor file in a <platform> element. Each
<platform> element named default. The default platform has an ActionScript-only implementation to use on all
platforms not specified with a
<platform> element names a target, such as iPhone-ARM or Windows-x86. You can also specify a
<platform> element. For more information, see “Native extension descriptor files” on
page 72.
Note: The implementation for at least one targeted platform must contain native code. If no targeted platforms require native code, then using native extensions is not the correct choice. In such cases, create a SWC library.

Extension availability at runtime

A native extension is available at runtime to an application in one of the following ways:
Application-bundling The extension is packaged with the AIR application, and installed with the application onto the
target device. An extension package typically contains the native and ActionScript implementations for multiple platforms, but can contain only one platform’s native and ActionScript implementations. Sometimes the extension package also contains an ActionScript-only implementation for unsupported platforms or for test platforms.
Device-bundling The extension is installed independently of any AIR application in a directory on the target device.
To use device-bundling, you typically work with the device manufacturer to install the extension on the device.
The following table shows which devices support application-bundling and device-bundling:
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Introducing native extensions for Adobe AIR
Application-bundling Device bundling
Android Yes No
iOS Yes No
Blackberry PlayBook Yes Yes
Windows Yes No
Mac OS X Yes No

Extension contexts

A native extension is loaded once each time an application runs. However, to use the native implementation, the ActionScript part of your extension calls a special ActionScript API to create an extension context.
A native extension can do either of the following.
Create only one extension context.
Only one extension context is typical for a simpler extension that provides only one set of functions in the native implementation.
Create multiple extension contexts that co-exist.
Multiple extension contexts are useful to associate ActionScript objects with native objects. Each association between an ActionScript object and a native object is one extension context instance. These extension context instances can have different context types. The native implementation can provide a different set of functions for each context type.
6
Each extension context can have context-specific data that you define and use in your native implementation.
An extension context can only be created by the ActionScript code in an extension. It cannot be created by the native code or by the application code.

Task overview to create a native extension

To create a native extension, do the following tasks:
1 Define the methods and properties of the ActionScript extension classes.
2 Code the ActionScript extension classes.
See “Coding the ActionScript side” on page 7.
3 Code the native implementation.
See “Coding the native side with C” on page 15 and “Coding the native side with Java” on page 30.
4 Build the ActionScript side and the native side, create an extension descriptor file, and package the extension and
its resources.
See “Packaging a native extension” on page 39 for all devices.
5 Document the public interfaces of the ActionScript extension class.
Typically, as with any software development, working through these steps is an iterative process.
Last updated 1/27/2017

Chapter 2: Coding the ActionScript side

A native extension is made of two parts:
ActionScript extension classes you define.
A native implementation.
The ActionScript extension classes access and exchange data with the native implementation. This access is provided with the ActionScript class ExtensionContext. Only ActionScript code that is part of an extension can access the ExtensionContext class methods.
Coding the ActionScript side of your extension includes the following tasks:
Declaring the public interfaces of your ActionScript extension class.
Using the static method ExtensionContext.createExtensionContext() to create an ExtensionContext
instance.
Using the call() method of the ExtensionContext instance to call methods in the native implementation.
Adding event listeners to the ExtensionContext instance to listen for events dispatched from the native
implementation.
Using the dispose() method to delete the ExtensionContext instance.
Sharing data between the ActionScript side and the native side. The data shared can be any ActionScript object.
Using the getExtensionDirectory() method to access the directory in which the extension is installed. All
information and resources related to the extension are in this directory. (An exception to this rule exists for iOS devices.)
For examples of native extensions, see Native extensions for Adobe AIR.
7
For more information about the ExtensionContext class, see the ActionScript 3.0 Reference for the Adobe Flash
Platform.

Declare the public interfaces

The first step in creating a native extension is determining the extension’s public interfaces. Application code uses these public interfaces to interact with the extension. ActionScript code goes in files with the .as extension. Create a .as file with your class definition. For example, the following code shows the declaration of a simple TVChannelController extension class, without yet filling in its implementation. This simple class allows an application to manipulate the channel setting on a hypothetical TV.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the ActionScript side
package com.example {
public class TVChannelController extends EventDispatcher {
public function TVChannelController() { }
public function set currentChannel(channelToSet:int):void { }
public function get currentChannel():int { }
}
}
Note: When designing your public interfaces, consider whether you will release subsequent versions of your extension. If so, consider backward compatibility support in your initial design. For more information about backward compatibility issues for device-bundled extensions, see
Native extension backward compatibility” on page 13.

Check for native extension support

8
A best practice is to always define a public interface that provides a handshake between the native extension and the AIR application. Instruct AIR application developers using your extension to check this method before calling any other extension method.
For example, consider an ActionScript extension class public interface called isSupported(). The isSupported() method allows an AIR application to make logic decisions based on whether the device on which the application is running supports the extension. If
isSupported() returns false, the AIR application must decide what to do without
the extension. For example, the AIR application can decide to exit.

Create an ExtensionContext instance

To begin working with the native implementation, the ActionScript extension class uses the ExtensionContext static method
package com.example {
}
createExtensionContext(). This method returns a new instance of the ExtensionContext class.
public class TVChannelController extends EventDispatcher {
private var extContext:ExtensionContext;
public function TVChannelController() {
extContext = ExtensionContext.createExtensionContext(
"com.example.TVControllerExtension", "channel");
} . . .
}
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the ActionScript side
In this example, the constructor calls createExtensionContext(). Although your extension classes can call
createExtensionContext() in any method, typically a constructor or other initialization method calls it. Save the
returned ExtensionContext instance in a data member of the class.
Note: Calling createExtensionContext() as part of a static data member’s definition is not recommended. Doing so means that the runtime creates the extension context earlier than the application needs it. If the application’s execution path does not eventually use the extension, creating the context wastes device resources.
The method createExtensionContext() takes two parameters: an extension ID and a context type.

The extension ID

The method createExtensionContext() takes a String parameter that is the identifier, or name, of the extension. This name is the same name you use in the extension descriptor file in the descriptor file when you package your extension). The application developers also use this name in the element in their application descriptor file. If an extension with the specified name is not available, then
createExtensionContext() returns Null.
To avoid name conflicts, Adobe recommends using reverse DNS for an extension ID. For example, the ID of the TVControllerChannel extension is
com.example.TVControllerExtension. Because all extensions share a single,
global namespace, using reverse DNS for the extension ID avoids name conflicts between extensions.
id element. (You create the extension
extensionID
9

The context type

The method createExtensionContext() takes a String parameter that is the context type for the new extension context. This string specifies more information about what the new extension context is to do.
For example, suppose the extension com.example.TVControllerExtension can manipulate both channel and volume settings. Passing
"channel" or "volume" in createExtensionContext() indicates which functionality the new
extension context will be used for. Another ActionScript class in the extension, such as TVVolumeController, could
createExtensionContext() with "volume" for the contextType value. The native implementation uses the
call contextType value in its context initialization.
Typically, each possible context type value you define corresponds to a different set of methods in your native implementation. The context type, therefore, corresponds to what is, in effect, a class in your native implementation. If you call
createExtensionContext()multiple times with the same context type, typically your native
implementation creates multiple instances of a particular native class.
When the context types of multiple calls to createExtensionContext()are different, the native side typically performs different initializations. Depending on the context type, the native side can create an instance of a different native class and can provide a different set of native functions.
Note: A simple extension often has only one context type. That is, it has only one set of methods in the native implementation. In this simple case, the context type String parameter can be
Null.

Call a native function

After the ActionScript extension class has called ExtensionContext.createExtensionContext(), it can call methods in the native implementation. The TVChannelController example calls native methods
"setDeviceChannel" and "getDeviceChannel" as follows:
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the ActionScript side
package com.example {
public class TVChannelController extends EventDispatcher {
private var extContext:ExtensionContext; private var channel:int;
public function TVChannelController() {
extContext = ExtensionContext.createExtensionContext(
"com.example.TVControllerExtension", "channel");
}
public function set currentChannel(channelToSet:int):void {
extContext.call("setDeviceChannel", channelToSet);
}
public function get currentChannel():int {
channel = int (extContext.call("getDeviceChannel")); return channel;
}
}
10
The call() method of ExtensionContext takes these parameters:
functionName. This string represents a function in the native implementation. In the TVChannelController
example, these strings are different from the ActionScript method names. You can choose to make the names the same. You can also choose whether a represents. In your native implementation, you provide the association between this native function. The association is in an output parameter of your
functionName string is the same as the name of the native function that it
functionName string and the
FREContextInitializer() method. See
Extension context initialization” on page 17.
An optional list of parameters. Each parameter is passed to the native function. A parameter can be a primitive type,
such as an int, or any ActionScript Object.
The return value of the call() method of ExtensionContext is a primitive type or any ActionScript Object. The subclass of Object that it returns depends on what the native function returns. For example, the native function
"getDeviceChannel" returns an int.

Listen for events

The native implementation can dispatch events that the ActionScript extension code can listen for. This mechanism allows the native implementation to perform tasks asynchronously, notifying the ActionScript side when the task is complete.
The event target is the ExtensionContext instance. Therefore, use the addEventListener() method of the ExtensionContext instance to subscribe to events from the native implementation.
The following example adds code to TVChannelController to receive an event from the native implementation. The application using the extension calls the ActionScript extension class method native function
"scanDeviceChannels".
scanChannels(), which in turn calls the
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the ActionScript side
This native function asynchronously scans for all available channels. When it has completed the scan, it dispatches an event. The of channels. The
onStatus() method handles the event by querying the native method "getDeviceChannels" for the list
onStatus() method stores the list in the scannedChannelList data member, and dispatches an
event to the application’s listening object. When the application object receives the event, it can call the ActionScript extension class property accessor
package com.example {
public class TVChannelController extends EventDispatcher {
private var extContext:ExtensionContext; private var channel:int; private var scannedChannelList:Vector.<int>;
public function TVChannelController() {
extContext = ExtensionContext.createExtensionContext(
extContext.addEventListener(StatusEvent.STATUS, onStatus); } . . . public function scanChannels():void {
extContext.call("scanDeviceChannels"); } public function get availableChannels():Vector.<int> {
return scannedChannelList; } private function onStatus(event:StatusEvent):void {
if ((event.level == "status") && (event.code == "scanCompleted")) {
scannedChannelList = (Vector.<int>)(extContext.call("getDeviceChannels")); dispatchEvent (new Event ("scanCompleted") );
} }
}
}
availableChannels.
"com.example.TVControllerExtension", "channel");
11
The example illustrates the following points:
The native implementation can dispatch only a StatusEvent object. Therefore, the addEventListener() method
listens for the event type
StatusEvent.STATUS.
The native implementation sets the code and level properties of the StatusEvent object. You can define the strings
you want to use for these properties. In this example, the native implementation sets the
status" and the code property to "scanCompleted". Typically, the level property of a StatusEvent has the value
"status", "info", or "error".
level property to
Because TVChannelController is a subclass of EventDispatcher, it can also dispatch an event. In this example, it
dispatches an Event object with the
type property "scanCompleted". Any ActionScript object interested in this
event can listen for it. For example, the following code shows a snippet from an AIR application that uses this extension. The application creates a TVChannelController object. Then, it asks the TVChannelController object to scan for channels. Then it waits for the scan to complete.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the ActionScript side
var channelController:TVChannelController = new TVChannelController(); channelController.addEventListener("scanCompleted", onChannelsScanned); channelController.scanChannels(); var channelList:Vector.<int>;
private function onChannelsScanned(evt:Event):void {
if (evt.type == "scanCompleted") {
channelList = channelController.availableChannels;}
}

Dispose of an ExtensionContext instance

The ActionScript extension class can dispose of the ExtensionContext instance by calling the ExtensionContext method example, the TVChannelController class can add a method for cleaning up:
public function dispose (): void {
}
dispose(). This method notifies the native implementation to clean up resources that the instance uses. For
extContext.dispose(); // Clean up other resources that the TVChannelController instance uses.
12
Your ActionScript extension class does not have to explicitly call the ExtensionContext instance’s dispose()method. In this case, the runtime calls it when the runtime garbage collector disposes of the ExtensionContext instance. A best practice, however, is to explicitly call
dispose(). An explicit call to dispose()typically cleans up resources much
sooner than waiting for the garbage collector.
Whether called explicitly or by the garbage collector, the ExtensionContext dispose() method results in a call to the native implementation’s context finalizer. For more information, see
Extension context finalization” on page 18.

Access the native extension’s directory

Sometimes extensions include additional files, such as images. An extension sometimes also wants to access the information in the extension descriptor file, such as the extension version number.
To access these files for extensions on all devices except iOS devices, use the ExtensionContext class static method
getExtensionDirectory(). For example:
var extDir:File = ExtensionContext.getExtensionDirectory("com.example.TVControllerExtension");
Pass the name of the extension to getExtensionDirectory(). This String value is the same name you use in:
the extension descriptor file in the id element.
the extension ID parameter you pass to ExtensionContext.createExtensionContext().
The returned File instance refers to the base extension directory. The extension directory has the following structure:
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the ActionScript side
extension base directory/
platform independent files
META-INF/
ANE/
extension.xml
platform name/
platform dependent files and directories
Regardless where the extension directory is on the device, the extension’s files are always in the same location relative to the base extension directory. Therefore, use the returned File instance and File class methods to navigate to and manipulate specific files included with the extension.
The extension directory location depends on whether the extension is available through application-bundling or device-bundling as follows:
With application-bundling, the extension directory is located within the application directory.
With device-bundling, the extension directory location depends on the device.
An exception to using getExtensionDirectory() exists for ActionScript extensions for iOS devices. The resources for these extensions are not located in the extension directory. Instead, they are located in the top-level application directory. For more information, see
Resources on iOS devices” on page 54.
13
More Help topics
Extension availability at runtime” on page 5

Identify the calling application from a native extension

The ActionScript side of your extension can identify and evaluate the AIR application using the extension. For example, use the ActionScript class signature data. Then the ActionScript side can make runtime decisions based on this information.
Sometimes the native implementation has similar runtime decisions to make. In this case, the ActionScript side can
call() method of an ExtensionContext instance to report the application information to the native
use the implementation.
NativeApplication to get information about the AIR application, such as its ID and

Native extension backward compatibility

Backward compatibility and the extension’s public interfaces

A best practice is to maintain backward compatibility in your extension’s ActionScript public interfaces. Continue to support the extension’s classes, methods, properties, and events in all subsequent versions of the extension.
Device-bundled extensions have a more complex issue with regard to backward compatibility. Sometimes, the behavior of an extension is different between versions of an extension. For example, a particular method returns a value with a new meaning in a new version of the extension. When this behavior occurs for device-bundled extensions, an application can stop working correctly. This problem can occur if the application was built with a version of the extension that behaves differently than the version of the extension installed on the device. In this case, the application expects one behavior, but the installed extension provides a different behavior.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the ActionScript side
In such cases, the extension installed on the device can determine how to proceed. The extension can do the following:
Look up the extension version that the AIR application was built with as well as the version installed on the device.
Determine whether the extension’s behavior is different in the two versions.
If the AIR application was built with an older version of the extension, revert to the older version’s behavior.
Note: Typically an AIR application that was built with a newer version of an extension is not available on the device. For more information, see
Backward compatibility and the device’s application store” on page 14.
To look up the extension version number that the application was built with, do the following:
1 Get the application installation directory using File.applicationDirectory.
2
Use the File class APIs to access the extension.xml file of the extension that the application built against. The file is at:
<application directory>/META-INF/AIR/extensions/<extensionID>/META-INF/ANE/extension.xml
3 Read the contents of the extension.xml file and find the value of the <versionNumber> element.
To look up the installed extension’s version number, do the following:
1 Use the static method ExtensionContext.getExtensionDirectory() to get the base directory for the
extension.
2 Use the File class APIs to access the extension.xml file of the extension installed on the device. The file is at:
<extension base directory>/META-INF/ANE/extension.xml
14
3 Read the contents of the extension.xml file and find the value of the <versionNumber> element.

Backward compatibility and the device’s application store

An AIR application that was built with a newer version of the extension than is installed on the device is typically not available on the device. The application is not available because of how device manufacturers handle requests from the device’s application store to a server to download such an application. Adobe recommends the following handling to the device manufacturers:
Consider the case when the server downloads an application that uses a newer version of the extension. The server
also downloads the newer version of the extension. The device’s application store installs both the application and the newer version of the extension.
Consider the case when the server cannot download a newer version of the extension. The server also does not
download the application that uses that version of the extension. The device’s application store handles the scenario gracefully, informing the end user as needed.
Consider the case when the server downloads an application that uses a newer version of the extension, but does
not download the newer version of the extension. The device’s application store does not allow the end user to run the application. The application store handles the scenario gracefully, informing the end user as needed.
Last updated 1/27/2017

Chapter 3: Coding the native side with C

Some devices use the C programming language in their native implementations. If you are targeting your native extension for such a device, use the native extensions C API to code the native side of your extension.
The C API is in the file FlashRuntimeExtensions.h. The file is available in the AIR SDK in the include directory. The AIR SDK is available at
The AIR runtime connects the ActionScript side of an extension to the native side of the extension.
Using the C API, you do the following tasks:
Initialize the extension.
Initialize each extension context when it is created.
Define functions that the ActionScript side can call.
Dispatch events to the ActionScript side.
Access data passed from the ActionScript side, and pass data back to the ActionScript side.
Create and access context-specific native data and context-specific ActionScript data.
Clean up extension resources when the extension’s work is done.
For details about each C API function, such as parameters and return values, see “Native C API Reference” on page 81.
http://www.adobe.com/products/air/sdk/.
15
For examples of native extensions that use the C API, see Native extensions for Adobe AIR.

Extension initialization

The runtime calls an extension initialization function on the native side. The runtime calls this initialization function once each time the application that uses the extension runs. Specifically, the runtime calls the initialization function the first time the extension calls
The function initializes data that all extension contexts can use. Define your extension initializer function with the signature of
For example:
void MyExtensionInitializer
{ extDataToSet = NULL; // This example does not use any extension data. *ctxInitializerToSet = &MyContextInitializer; *ctxFinalizerToSet = &MyContextFinalizer; }
The FREInitializer() method that you define returns the following data to the runtime:
FREInitializer().
(void** extDataToSet, FREContextInitializer* ctxInitializerToSet, FREContextFinalizer* ctxFinalizerToSet)
A pointer to the data that the runtime later passes to each new extension context. For example, if all extension contexts
use the same utility library, this data can include a pointer to the library. This data is called the extension data.
The extension data can be any data you choose. It can be a simple primitive data type, or a pointer to a structure you define. In this example, the pointer is
ExtensionContext.createExtensionContext() for any context.
NULL because the extension does not have a use for this data.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C
A pointer to the context initialization function. Each time the ActionScript side calls
ExtensionContext.createExtensionContext(), the runtime calls an extension context initialization function
that you provide. See
FREContextInitializer()” on page 88.
A pointer to the context finalizer function. The runtime calls this function when the runtime disposes of the
extension context. This call occurs when the ActionScript side calls the ExtensionContext instance’s method. If
dispose() is not called, the runtime garbage collects the ExtensionContext instance. See
dispose()
FREContextFinalizer()” on page 87.
For application-bundled extensions, your implementation of FREInitializer()can have any name. Specify the name of the initialization function in the extension descriptor file. See
Native extension descriptor files” on page 72.
For device-bundled applications, how to specify the extension initializer function is device-dependent.
The following sequence diagram shows the AIR runtime calling the FREInitializer() function. It also shows context initialization. For more information, see
Extension context initialization” on page 17.
16
AIR
ActionScript extension classes
application
ActionScript extension class API
Extension initialization sequence
for extension A
ExtensionContext. createExtensionContext()
• extension ID
• context type
AIR
runtime
FREInitializer()
(called only on rst call to this extension’s createExtensionContext())
pointer to extension data
pointer to FREContextInitializer()
pointer to FREContextFinalizer()
FREContextInitializer()
• extension data
• context type
• FREContext value
FRESetContextNativeData()
• FREContext value
• native data
FREContextInitializer() returns an array of pointers to FRENamedFunction structures
Each structure contains:
• a pointer to a native function
• the name of the function as called from ActionScript
• a pointer to function data
C native implementation
for extension A
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C

Extension context initialization

To use the native C methods, the ActionScript side of your extension first calls the static method
ExtensionContext.createExtensionContext(). Calling createExtensionContext() causes the runtime to do
the following:
Create an ExtensionContext instance.
Create internal data it uses to track the extension context.
Call the extension context initialization function.
The extension context initialization function initializes the native implementation for the new extension context. Define your extension context initializer function with the signature of
For example, the Vibration example uses the following function:
void ContextInitializer(void* extData, const uint8_t* ctxType, FREContext ctx,
uint32_t* numFunctionsToSet, const FRENamedFunction** functionsToSet) {
*numFunctionsToSet = 2;
FRENamedFunction* func = (FRENamedFunction*)malloc(sizeof(FRENamedFunction)*2); func[0].name = (const uint8_t*)"isSupported"; func[0].functionData = NULL; func[0].function = &IsSupported;
func[1].name = (const uint8_t*)"vibrateDevice"; func[1].functionData = NULL; func[1].function = &VibrateDevice;
*functionsToSet = func;
}
FREContextInitializer().
17
A context initialization function receives the following input parameters:
The extension data that the extension initialization function had created. See “Extension initialization” on page 15.
The context type. The ActionScript method ExtensionContext.createExtensionContext()is passed a
parameter that specifies the context type. The runtime passes this string value to the context initialization function. The function then uses the context type to choose the set of methods in the native implementation that the ActionScript side can call. Each context type typically corresponds to a different set of methods. See
The context
type” on page 9.
The value of the context type is any string agreed to between the ActionScript side and the native side.
If your extension has only one set of methods in the native implementation, pass null or an empty string in
ExtensionContext.createExtensionContext(). Then ignore the context type parameter in the extension
context initializer.
A FREContext value. The runtime creates internal data when it creates an extension context. It associates the
internal data with the ExtensionContext class instance on the ActionScript side.
When your native implementation dispatches an event the ActionScript side, it specifies this FREContext value. The runtime uses the FREContext value to dispatch the event to the corresponding ExtensionContext instance. See “FREDispatchStatusEventAsync()” on page 95.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C
Also, native functions can use this value to access and set the context-specific native data and context-specific ActionScript data.
The extension context initialization function sets the following output parameters:
An array of native functions. The ActionScript side can call each of these functions by using the ExtensionContext
instance’s
The type of each array element is FRENamedFunction. This structure includes a string which is the name the ActionScript side uses to call the function. The structure also includes a pointer to the C function you write. The runtime associates the name with the C function. Although the name string does not have to match the actual function name, typically you use the same name.
call() method.
The number of functions in the array of native functions.
A sequence diagram showing the AIR runtime calling the FREContextInitializer() function is in “Extension
initialization” on page 15.
More Help topics
Vibration native extension example
18

Context-specfic data

Context-specific data is specific to an extension context. (Recall that extension data is for all extension contexts in an extension). The context initialization method, context finalization method, and native extension methods can create, access, and modify the context-specific data.
The context-specific data can include the following:
Native data. This data is any data you choose. It can be a simple primitive data type, or a structure you define. See
FREGetContextNativeData()” on page 99 and “FRESetContextNativeData()” on page 114.
ActionScript data. This data is an FREObject variable. Since an FREObject variable corresponds to an ActionScript
class object, this data allows you to save and later access an ActionScript object. See “FREGetContextActionScriptData()” on page 98 and “FRESetContextActionScriptData()” on page 113. Also see “The FREObject type” on page 22.
A sequence diagram showing the native implementation setting context-specific native data is in “Extension
initialization” on page 15. A sequence diagram showing the native implementation getting the context-specific data is
in “Extension functions” on page 20.

Extension context finalization

The ActionScript side of your extension can call the dispose() method of an ExtensionContext instance. Calling
dispose() causes the runtime to call the context finalization function of your extension. Define your extension
context finalization function with the signature of
FREContextFinalizer().
This method has one input parameter: the FREContext value. You can pass this FREContext value to
FREGetContextNativeData() and FREGetContextActionScriptData() to access the context-specific data. Clean
up any data and resources associated with this context.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C
If the ActionScript side does not call dispose(), the runtime garbage collector disposes of the ExtensionContext instance when no more references to it exist. At that time, the runtime calls your context finalization function.
The following sequence diagram shows the AIR runtime calling the FREContextFinalizer() function:
19
AIR
application
ActionScript extension class API
Extension context finalization sequence
ActionScript extension classes
for extension A
ExtensionContext.dispose()
AIR
runtime
FREContextFinalizer()
• FREContext value
C native implementation
for extension A

Extension finalization

The C API provides an extension finalization function for the runtime to call when it unloads the extension. However, the runtime does not always unload an extension. Therefore, the runtime does not always call the extension finalization function.
Define your extension finalization function with the signature of FREFinalizer(). This method has one input parameter: the extension data you created in your extension initialization function. Clean up any data and resources associated with this extension.
For application-bundled extensions, your implementation of FREFinalizer()can have any name. Specify the name of the finalization function in the extension descriptor file. See
For device-bundled applications, how to specify the extension finalization function is device-dependent.
Last updated 1/27/2017
Native extension descriptor files” on page 72.
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C

Extension functions

The ActionScript side of your extension calls C functions you implement by calling the ExtensionContext instance’s
call() method. The call() method takes these parameters:
The name of the function. You provided this name in an output parameter of your context initialization function.
This name is an arbitrary string agreed to between the ActionScript side and the native side. Typically, it is the same name as the actual name of the native C function. However, these names can be different because the runtime associates the arbitrary name with the actual function.
A list of arguments for the native function. These arguments can be any ActionScript objects: primitive types or
ActionScript class objects.
Define each of your native functions with the same function signature: FREFunction(). The runtime passes the following parameters to each native function:
The FREContext value. The native function can use this value to access and set the context-specific data. Also, the
native implementation uses the FREContext value to dispatch an asynchronous event back to the ActionScript side.
A pointer to the data associated with the function. This data is any native data. When the runtime calls the native
function, it passes the function this data pointer.
The number of function parameters.
The function parameters. Each function parameter has the type FREObject. These parameters correspond to
ActionScript class objects or primitive data types.
A native function also has a return value with the type FREObject. The runtime returns the corresponding ActionScript object as the return value for the ExtensionContext
call() method.
20
Note: Do not set a native function’s visibility to hidden. Use the default visibility.
The following sequence diagram shows an AIR application making a function call that results in calling a native C function named
FREFunctionF(). In this example, the C function:
Gets the context-specific native data.
Gets the int32 value of an ActionScript object.
Starts an asynchronous thread which later dispatches an event.
Note: The behavior of the C function FREFunctionF() is only a sample behavior to illustrate a call sequence.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C
21
AIR
application
ActionScript extension classes
ActionScript extension class API
for extension A
ExtensionContext.call()
• function name
• function arguments
AIR
runtime
FREFunctionF()
• FREContext value
• pointer to function data
• function arguments
FREGetContextNativeData()
• FREContext value
native data
FREGetObjectAsInt32()
• FREObject variable
int32 value
FREFunctionF returns
FREDispatchStatusEventAsync()
• FREContext value
• event code
• event level
FREDispatchStatusEventAsync() returns
C native implementation
for extension A
start asynchronous thread
• FREContext value
Asynchronous
native thread
StatusEvent
• event code
• event level
Native function sample call sequence

Dispatching asynchronous events

The native C code can dispatch asynchronous events back to the ActionScript side of your extension. For example, an extension method can start another thread to perform some task. When the task in the other thread completes, that thread calls event is an ActionScript ExtensionContext instance.
The sequence diagram in “Extension functions” on page 20 shows a native C function starting an asynchronous thread, which later dispatches an event.
More Help topics
FREDispatchStatusEventAsync()” on page 95
FREDispatchStatusEventAsync() to inform the ActionScript side of the extension. The target of the
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C

The FREObject type

A variable of type FREObject refers to an object that corresponds to an ActionScript class object or primitive type. You use an FREObject variable in your native implementation to work with ActionScript data. A primary use of the FREObject type is for native function parameters and return values.
When you write a native function, you decide on the order of the parameters. Since you also write the ActionScript side, you use that parameter order in the ExtensionContext instance’s native function parameter is an FREObject variable, you know its corresponding ActionScript type.
Similarly you decide on the ActionScript type of the return value, if any, of a native function. The call() method returns an object of this type. Although the native function return value is always an FREObject variable, you know its corresponding ActionScript type.
The extensions C API provides functions for using the object that an FREObject variable refers to. Because these objects correspond to ActionScript data, these C API functions are how you access an ActionScript class object or primitive data variable. The C APIs that you use depend on the type of the ActionScript object. The types are the following:
An ActionScript primitive data type
An ActionScript class object
An ActionScript String object
An ActionScript Array or Vector class object
An ActionScript ByteArray class object
An ActionScript BitmapData class object
Note: You can call the extensions C APIs only from the same thread as the one in which the FREFunction function is running. The one exception is the C API for dispatching an event to the ActionScript side. You can call that function,
FREDispatchStatusEventAsync(), from any thread.
call() method. Therefore, although every
22

Determining the type of an FREObject variable

Sometimes you don’t know the type of ActionScript Object that an FREObject variable corresponds to. To determine the type, use the C API function
FREResult FREGetObjectType( FREObject object, FREObjectType *objectType );
Once you know the type, use the appropriate C APIs to work with the value. For example if the type is
FRE_TYPE_VECTOR, use the C APIs in “Working with ActionScript Array and Vector objects” on page 27 to work with
the Vector object.
FREGetObjectType():

FREObject validity

If you attempt to use an invalid FREObject variable in a C API call, the C API returns an FRE_INVALID_OBJECT return value.
Any FREObject variable is valid only until the first FREFunction function on the call stack returns. The first FREFunction function on the call stack function is the one that the runtime calls due to the ActionScript side calling the ExtensionContext instance’s
The following illustration illustrates this behavior:
call() method.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C
FREFunctionC()
can use myobj
3
FREFunctionB()
creates FREObject myobj as a
global variable or allocated on the heap
2
FREFunctionA()
1
AIR runtime
FREObject validity on the call stack
calls indirectly
calls indirectly
calls
returns to
4
FREFunctionB() which can use myobj
5
returns to FREFunctionA() which can use myobj
6
returns to runtime
7
calls
FREFunctionA()
cannot use myobj
Note: An FREFunction function can indirectly call another FREFunction function. For example, FREFunctionA() can call a method of an ActionScript object. That method then can call
FREFunctionB().
Therefore, when using an FREObject variable, consider the following:
23
Any FREObject variable passed to an FREFunction function is valid only until the first FREFunction function on
the call stack returns.
Any FREObject variable that any native function creates using the extensions C API is valid only until the first
FREFunction function on the call stack returns.
You cannot use an FREObject variable in another thread. Only use the FREObject variable in the same thread as
the native function that received or created the variable.
You cannot save an FREObject variable, for example in global data, between calls to FREFunction functions.
Because the variable becomes invalid when the first FREFunction function on the call stack returns, the saved variable is useless. However, you can save the corresponding ActionScript object by using the method
FRESetContextActionScriptData().
After an FREObject variable becomes invalid, the corresponding ActionScript object can still exist. For example, if
an FREObject variable is a return value of an FREFunction function, its corresponding ActionScript object is still referenced. However, once the ActionScript side deletes its references, the runtime disposes of the ActionScript object.
You cannot share FREObject variables between extensions.
Note: You can share FREObject variables between extension contexts of the same extension. However, as in any case, the FREObject variable becomes invalid when the first FREFunction function on the call stack returns to the runtime.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C

Working with ActionScript primitive types and objects

Working with ActionScript primitive types

In your native functions, an input parameter can correspond to a primitive ActionScript type. All native function parameters are of type FREObject. Therefore, to work with an ActionScript primitive type input parameter, you get the ActionScript value of the FREObject parameter. You store the value in a corresponding primitive C data type variable. Use the following C API functions:
FREGetObjectAsInt32()
FREResult FREGetObjectAsInt32(FREObject object, int32_t *value);
FREGetObjectAsUint32()
FREResult FREGetObjectAsUint32(FREObject object, uint32_t *value);
FREGetObjectAsDouble()
FREResult FREGetObjectAsDouble(FREObject object, double *value);
FREGetObjectAsBool(),
FREResult FREGetObjectAsBool (FREObject object, bool *value);
24
If an output parameter or return value corresponds to a primitive ActionScript type, you create the ActionScript primitive using a C API function. You provide a pointer to an FREObject variable and the value of the primitive in a C data variable. The runtime creates the ActionScript primitive and sets the FREObject variable to correspond to it. Use the following C API functions:
FRENewObjectFromInt32()
FREResult FRENewObjectFromInt32(int32_t value, FREObject *object);
FRENewObjectFromUint32()
FREResult FRENewObjectFromUint32(uint32_t value, FREObject *object);
FRENewObjectFromDouble()
FREResult FRENewObjectFromDouble(double value, FREObject *object);
FRENewObjectFromBool(),
FREResult FRENewObjectFromBool (bool value, FREObject *object);

Working with ActionScript String objects

In your native functions, an input parameter can correspond to an ActionScript String class object. All native function parameters are of type FREObject. Therefore, to work with an ActionScript String parameter, you get the ActionScript String value of the FREObject parameter. You store the value in a corresponding C string variable. Use the C API function
FREResult FREGetObjectAsUTF8(
);
FREGetObjectAsUTF8():
FREObject object,
uint32_t* length,
const uint8_t** value
After calling FREGetObjectAsUTF8(), the ActionScript String value is in the value parameter, and the length parameter tells the length of the value string in bytes.
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C
If an output parameter or return value corresponds to an ActionScript String class object, you create the ActionScript String object using a C API. You provide a pointer to a FREObject variable and the string value and length in bytes in C string variables. The runtime creates the ActionScript String object and sets the FREObject variable to correspond to it. Use the C API function
FREResult FRENewObjectFromUTF8(
uint32_t length,
const uint8_t* value,
FREObject* object
);
FRENewObjectFromUTF8():
The value parameter strings must use UTF- 8 encoding and include the null terminator.
Note: All string parameters to any C API function use UTF-8 encoding and include the null terminator.

Working with ActionScript Class objects

In your native functions, an input parameter can correspond to an ActionScript class object. Since all native function parameters are of type FREObject, the C APIs provide functions for manipulating class objects using an FREObject variable.
Use the following C API functions to get and set a property of the ActionScript class object:
25
FREGetObjectProperty()
FREResult FREGetObjectProperty(
FREObject object, const uint8_t* propertyName,
FREObject* propertyValue, FREObject* thrownException );
FRESetObjectProperty()
REResult FRESetObjectProperty(
FREObject object,
const uint8_t* propertyName,
FREObject propertyValue,
FREObject* thrownException );
Use the following C API to call a method of an ActionScript class object:
FRECallObjectMethod()
FREResult FRECallObjectMethod(
FREObject object, const uint8_t* methodName, uint32_t argc, FREObject argv[], FREObject* result, FREObject* thrownException
);
If an output parameter or return value corresponds to an ActionScript class object, you create the ActionScript object using a C API. You provide a pointer to an FREObject variable plus FREObject variables to correspond to parameters to the ActionScript class constructor. The runtime creates the ActionScript class object and sets the FREObject variable to correspond to it. Use the following C API function:
FRENewObject()
Last updated 1/27/2017
DEVELOPING NATIVE EXTENSIONS
Coding the native side with C
FREResult FRENewObject(
const uint8_t* className, uint32_t argc, FREObject argv[], FREObject* object, FREObject* thrownException
);
Note: These general ActionScript object manipulation functions apply to all ActionScript class objects. However, the ActionScript classes Array, Vector, ByteArray, and BitmapData are special cases because they each involve large amounts of data. Therefore, the C API provides additional specific functions for manipulating objects of these special cases.

Working with ActionScript ByteArray objects

Use the ActionScript ByteArray class to efficiently pass many bytes between the ActionScript side and native side of your extension. In your native functions, an input parameter, output parameter, or return value can correspond to an ActionScript ByteArray class object.
As with other ActionScript class objects, an FREObject variable is the native side representation of an ActionScript ByteArray object. The C APIs provide functions for manipulating a ByteArray class object using an FREObject variable. Use the ActionScript ByteArray object’s properties and to call its methods.
FRESetObjectProperty(), FREGetObjectProperty(), and FRECallObjectMethod()to get and set
26
However, to manipulate the bytes of the ByteArray object in the native code, use the C API function
FREAcquireByteArray(). This method accesses the bytes of a ByteArray object that was created on the ActionScript side:
FREResult FREAcquireByteArray(
FREObject object,
FREByteArray* byteArrayToSet ); // The type FREByteArray is defined as:
typedef struct {
uint32_t length;
uint8_t* bytes; } FREByteArray;
After you have manipulated the bytes, use the C API FREReleaseByteArray():
FREResult FREReleaseByteArray( FREObject object );
Note: Do not call any C API functions between the calls to FREAcquireByteArray() and FREReleaseByteArray(). This prohibition is because other calls could, as a side effect, execute code that invalidates the pointer to the byte array contents.
Example
This example shows the ActionScript side of the extension creating a ByteArray object and initializing its bytes. Then it calls a native function to manipulate the bytes.
Last updated 1/27/2017
Loading...
+ 111 hidden pages