HOWTO: Transfer Number, String, int/uint and Boolean with AIR Native Extensions for iOS back and forth
February 7th, 2012
Casting basic types from ActionScript 3 to C
Your probably first and immediate question when programming ANE for iOS is: “How to transfer data from AS3 to C and back to AS3?”. Once you break through this essential stage you enter the world of endless possibilities in Adobe AIR with native extensions.
There has been already plenty of articles on how to begin writing your native extensions, I am not going to explain that, just share the source code needed for that.
I am using Adobe Flash Builder 4.6 with ANE support for AS3 and Apple Xcode for coding the C part + packaging the static library (*.a file).
But let me quickly remind you the workflow. You need 3 projects, one is Flex Library project in FB (AS3 interface for C as *.swc), second is native library in Xcode (C interface and implementation as static library *.a), third is the actual test project in FB to run the native extension (*.ane).
Fig: Native Extension Creation Process
In this tutorial I want to illustrate how to transfer some basic types like Number, String, int/uint and Boolean from AS3 to C, process them and return back to AS3. In the next tutorial, we will look into more complex data types like Array, ByteArray and BitmapData.
*UPDATE: Casting Array and Vector from AS3 to C
Good starting point: Native C API Reference for Adobe AIR extensions. There is also a good page Coding native side with C for AIR.
But there is nothing better than samples. Let’s dig into some real code:
Number (AS3->C->AS3) Sum function
AS3 part:
public function sum(number1:Number,number2:Number):Number{ // call C function sum with 2 arguments, number 1 and number2 and return a value var ret:Number = context.call("sum",number1,number2) as Number; return ret; }
C part:
FREObject sum(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]){ // argc ... argument count, uint // argv ... argument values, Array // retrieve first argument and write it to a variable double number1; FREGetObjectAsDouble(argv[0], &number1); // retrieve second argument and write it to a variable double number2; FREGetObjectAsDouble(argv[1], &number2); // add first and second number together double sum = number1 + number2; // write computed sum to FREObject that will be returned back to AS3 FREObject sumToReturn = nil; FRENewObjectFromDouble(sum, &sumToReturn); return sumToReturn; }
int (AS3->C->AS3) Subtract function
AS3 part:
public function subtract(int1:int,int2:int):int{ var ret:Number = context.call("subtract",int1,int2) as int; return ret; }
C part:
FREObject subtract(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]){ int32_t int1; FREGetObjectAsInt32(argv[0], &int1); int32_t int2; FREGetObjectAsInt32(argv[1], &int2); int32_t sum = int1 - int2; NSLog(@"%d-%d=%d",int1,int2,sum); FREObject sumToReturn = nil; FRENewObjectFromInt32(sum, &sumToReturn); return sumToReturn; }
uint (AS3->C->AS3) Multiply function
AS3 part:
public function multiply(uint1:uint,uint2:uint):uint{ var ret:Number = context.call("multiply",uint1,uint2) as uint; return ret; }
C part:
FREObject multiply(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]){ uint32_t uint1; FREGetObjectAsUint32(argv[0], &uint1); uint32_t uint2; FREGetObjectAsUint32(argv[1], &uint2); uint32_t sum = uint1*uint2; NSLog(@"%d*%d=%d",uint1,uint2,sum); FREObject sumToReturn = nil; FRENewObjectFromUint32(sum, &sumToReturn); return sumToReturn; }
String (AS3->C->AS3) Concatenate function
AS3 part:
public function concatenate(str1:String,str2:String):String{ var ret:String = context.call("concatenate",str1,str2) as String; return ret; }
C/Obj-C part:
// in this sample I wanted to go even further and utilize Obj-C function for concatenating strings and also demonstrate how to pass strings between C and Obj-C
FREObject concatenate(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]){ // To be filled uint32_t string1Length; const uint8_t *string1; FREGetObjectAsUTF8(argv[0], &string1Length, &string1); uint32_t string2Length; const uint8_t *string2; FREGetObjectAsUTF8(argv[1], &string2Length, &string2); // Convert C strings to Obj-C strings NSString *string1ObjC = [NSString stringWithUTF8String:(char*)string1]; NSString *string2ObjC = [NSString stringWithUTF8String:(char*)string2]; // Concat strings NSString *returnString = [string1ObjC stringByAppendingString:string2ObjC]; // Convert Obj-C string to C UTF8String const char *str = [returnString UTF8String]; // Prepare for AS3 FREObject retStr; FRENewObjectFromUTF8(strlen(str)+1, (const uint8_t*)str, &retStr); // Return data back to ActionScript return retStr; }
Boolean (AS3->C->AS3) Opposite function
AS3 part:
public function opposite(bool:Boolean):Boolean{ var ret:Boolean = context.call("opposite",bool) as Boolean; return ret; }
C part:
FREObject opposite(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]){ uint32_t boolean; FREGetObjectAsBool(argv[0], &boolean); uint32_t oppositeValue = !boolean; FREObject retBool = nil; FRENewObjectFromBool(oppositeValue, &retBool); return retBool; }
Full C-part source code: IOSExtension.m
Download whole C-project for Xcode
Complete AS3 SWC lib part: IOSExtension.as
Test project source (SWF/IPA): IOSExtensionTest.as
For compiling native extension (*.ane) I use this command in Terminal.app.
compileExtension.sh file/script
unzip -o IOSExtension.swc /PATH/TO/FLEX_AIR_SDK/bin/adt -package -target ane IOSExtension.ane extension.xml -swc IOSExtension.swc -platform iPhone-ARM library.swf libIOSExtension.a
extension.xml looks like this:
<extension xmlns="http://ns.adobe.com/air/extension/2.5"> <id>com.krcha.IOSExtension</id> <versionNumber>1</versionNumber> <platforms> <platform name="iPhone-ARM"> <applicationDeployment> <nativeLibrary>libIOSExtension.a</nativeLibrary> <initializer>ADBEExtInitializer</initializer> <finalizer>ADBEExtFinalizer</finalizer> </applicationDeployment> </platform> </platforms> </extension>
Facebook comments:
9 Comments »
RSS feed for comments on this post. / TrackBack URL
[...] time I wrote about casting basic types from AS3 to C like Number, String, Boolean, int and uint. Now I’d like to cover two more complex types: [...]
Pingback by HOWTO: Transfer Array and Vector from AS3 to C with AIR Native Extensions for iOS — FlashRealtime.com — February 8, 2012 @ 5:28 pm
Really appreciate you sharing this article.Really looking forward to read more. Great.
Comment by Stefan Raposa — April 24, 2012 @ 3:31 pm
Great writeup. With respect to strings, I am writing C/C++ code with no objective C, so no NSString manipulation for me. Do you have any examples of how to take a wstring and pack it into a FREObject to hand back to AS3?
Comment by Brad — April 26, 2012 @ 7:34 am
Really NICE..
thanks
Comment by wow — May 30, 2012 @ 1:22 pm
Is that possible to create adobe native extensions using C#.net?
if yes then how
Thank you in advance
Comment by Mayur — December 3, 2012 @ 12:59 pm
Sir, can u please tell how to convert c#.net string into char of the ANE’s c code…
Comment by Mayur — December 5, 2012 @ 6:16 am
Thanks Tom! Just what i needed today!
Comment by Bruce — December 13, 2012 @ 1:07 pm
As usual you might have posted with several incredibly interesting items and also I have as of now added in
this specific blog to at least one I’ll pay attention to ! ! ! !
Comment by hire man and van kingston — December 27, 2012 @ 2:00 pm
Heya superb blog! Does running a blog like this
require a great deal of work? I have no expertise in programming however I had been hoping to start my
own blog soon. Anyway, if you have any ideas or tips for
new blog owners please share. I understand this is off subject but
I just needed to ask. Cheers!
Comment by best electric toothbrush review — January 4, 2013 @ 1:30 am