9 July 2012
To make the most of this article, you’ll need a good understanding of ActionScript, C, Flash Builder, Xcode, and using tools from the command line.
Additional required other products (third-party/labs/open source)
Intermediate
In Part 1 of this series I showed how to exchange basic types such as Number, int, uint, String, and Boolean data between ActionScript 3 and C (or C++, C#, or Objective-C) for native extensions on iOS. In this article, I illustrate the same technique using arrays and Vector objects.
If you haven't done so already, I recommend reading Part 1 before proceeding with this article.
This example implements a native language reverseArray() function, which reverses the elements in an ActionScript Array object. For example, if it is provided [1,2,3] as an array it returns [3,2,1] .
Here is the ActionScript 3 code:
public function reverseArray(array:Array):Array{
var ret:Array= context.call("reverseArray",array) as Array;
return ret;
}
The C code is a bit more complex than the code for basic data types. It performs the following steps:
Here is the code:
FREObject reverseArray(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]){
FREObject arr = argv[0]; // array
uint32_t arr_len; // array length
FREGetArrayLength(arr, &arr_len);
FREObject populatedArray = NULL;
// Create a new AS3 Array, pass 0 arguments to the constructor (and no arguments values = NULL)
FRENewObject((const uint8_t*)"Array", 0, NULL, &populatedArray, nil);
FRESetArrayLength(populatedArray, arr_len);
NSLog(@"Going through the array: %d",arr_len);
int32_t j = 0;
for(int32_t i=arr_len-1; i>=0;i--){
// get an element at index
FREObject element;
FREGetArrayElementAt(arr, i, &element);
// OPTIONAL: get an int value out of the element
int32_t value;
FREGetObjectAsInt32(element, &value);
// log index and value
NSLog(@"Get item %d: %d",i,value);
NSLog(@"Set item %d: %d",j,value);
FRESetArrayElementAt(populatedArray, j, element);
j++;
}
return populatedArray;
}
The implementation for exchanging Vector variables is almost identical to the implementation for Array variables. The key difference is in the creation of the Vector object. For a Vector with integer elements, that will look like this:
FRENewObject((const uint8_t*)"Vector.<int>", 0, NULL, &populatedArray, nil);
Here is the ActionScript 3 code for reverseVector , which implements the same functionality as reverseArray :
public function reverseVector(vector:Vector.<int>):Vector.<int>{
var ret:Vector.<int>= context.call("reverseVector",vector) as Vector.<int>;
return ret;
}
Here is the C code:
FREObject reverseVector(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]){
FREObject arr = argv[0]; // array
uint32_t arr_len; // array length
FREGetArrayLength(arr, &arr_len);
FREObject populatedVector = NULL;
// Create a new AS3 Vector, pass 0 arguments to the constructor (and no arguments values = NULL)
FRENewObject((const uint8_t*)"Vector.<int>", 0, NULL, &populatedVector, nil);
FRESetArrayLength(populatedVector, arr_len);
NSLog(@"Going through the vector: %d",arr_len);
int32_t j = 0;
for(int32_t i=arr_len-1; i>=0;i--){
// get an element at index
FREObject element;
FREGetArrayElementAt(arr, i, &element);
// OPTIONAL: get an int value out of the element
int32_t value;
FREGetObjectAsInt32(element, &value);
// log index and value
NSLog(@"Get item %d: %d",i,value);
NSLog(@"Set item %d: %d",j,value);
FRESetArrayElementAt(populatedVector, j, element);
j++;
}
return populatedVector;
}
As I mentioned in Part 1, a good starting point for learning more about native extensions is the Native C API Reference for Adobe AIR extensions.
Part 3 of this series (to come soon) covers exchanging custom objects between ActionScript 3 and native extensions.
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.