必要条件

この記事に必要な予備知識

この記事を最大限活用するには、ActionScript、C言語、Flash Builder、Xcodeを十分に理解し、コマンドラインからのツールが使用できる必要があります。



必要となるほかの製品

ユーザーレベル

中級

iOS用のAIRネイティブ拡張機能のプログラミングを始める場合、最初に浮かぶ疑問はおそらく「ActionScript 3からC言語(またはC++やObjective-C)にどのようにデータを転送し、ActionScript 3に戻したらいいのか」ということでしょう。このことが理解できれば、Adobe AIRのネイティブ拡張機能が持つ限りない可能性を存分に活用することができます。

既にご存じと思いますが、Adobe AIR用のネイティブ拡張機能は、ActionScriptクラスと、ほかの方法では内蔵のActionScriptクラスで使用できない、デバイス固有のライブラリと機能を提供するネイティブコードを組み合わせたものです。ネイティブ拡張機能の基本について詳しくは、Adobe AIRデベロッパーセンターの「Native extensions for Adobe AIR」を参照してください。

この記事では、ActionScript 3とC言語の間で、Number、int、uint、String、Booleanなどの基本的なデータ型を転送する方法を説明します。C++やObjective-Cについても、同じ方法が使用できます。

説明を理解するには、ActionScript 3のAIRネイティブ拡張機能をサポートしたAdobe Flash Builder 4.6が必要です。またC言語のパートをコード化し、スタティックライブラリ(*.aファイル)をパッケージ化するには、Apple Xcodeも必要になります。

図1は、3つのプロジェクトを含むワークフローを示しています。最初のプロジェクトは、Flash BuilderのFlex Libraryプロジェクト(ネイティブ言語コード用のActionScript 3インターフェイスで、SWCファイル)です。2番目のプロジェクトは、Xcodeのネイティブライブラリプロジェクト(C言語のインターフェイスと実装で、スタティックライブラリ*.aファイル)です。3番目のプロジェクトは、ネイティブ拡張機能を実行する、Flash Builderのテストプロジェクト(*.ane)です。

ActionScript 3とC言語間での基本的なデータ型の交換

この後に示すコード例は、基本的なデータ型を、ActionScript 3からC言語へ転送する方法、処理する方法、ActionScript 3へ戻す方法を示しています。

Number値の交換

最初の例では、ネイティブ言語sum()関数を使用して、2つのNumber変数を追加します。

ActionScript 3のコードを次に示します。

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実装がActionScriptクラスオブジェクトまたはプリミティブデータ型変数にアクセスすると、FREObject変数が使用されます。ランタイムによって、この変数が対応するActionScriptオブジェクトに関連付けられます。

対応するCコードは次のとおりです。

FREObject sum(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[]){ // argc ... argument count, uint // argv ... argument values, Array // retrieve the first argument and write it to a variable double number1; FREGetObjectAsDouble(argv[0], &number1); // retrieve the 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 a FREObject variable, which will be returned back to AS3 FREObject sumToReturn = nil; FRENewObjectFromDouble(sum, &sumToReturn); return sumToReturn; }

int値の交換

2番目の例では、2つの整数変数の違いを検索します。

ActionScript 3のパートを次に示します。

public function subtract(int1:int,int2:int):int{ var ret:Number = context.call("subtract",int1,int2) as int; return ret; }

Cコードは次のとおりです。

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値の交換

この例では、unit値を使用してかけ算を計算します。

ActionScript 3のコードを次に示します。

public function multiply(uint1:uint,uint2:uint):uint{ var ret:Number = context.call("multiply",uint1,uint2) as uint; return ret; }

Cコードは次のとおりです。

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値の交換

この例では、手順を追加して、連結文字列用にObjective-Cを使用します。したがって、この例ではC言語とObjective-C間での文字列の交換方法についても示します。

ActionScript 3のコードを次に示します。

public function concatenate(str1:String,str2:String):String{ var ret:String = context.call("concatenate",str1,str2) as String; return ret; }

CとObjective-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値の交換

最後の例では、渡されたBoolean値を反転して返します。

ActionScript 3の関数を次に示します。

public function opposite(bool:Boolean):Boolean{ var ret:Boolean = context.call("opposite",bool) as Boolean; return ret; }

これはC言語の対応パートです。

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; }

ネイティブ拡張機能の構築

ネイティブ拡張機能(.aneファイル)をコンパイルするため、コマンドラインで次のコマンドを使用しました。

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ファイルの内容は次のとおりです。

<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>

次のステップ

ネイティブ拡張機能の詳細を学習する場合、Adobe AIR拡張機能の「ネイティブ C APIリファレンス」から始めることをお勧めします。ネイティブ言語に対するC言語の使用について詳しくは、「C を使用したネイティブ側のコーディング」を参照してください。

このシリーズのパート2では、ArrayオブジェクトやVectorオブジェクトなど、より複雑なデータ型について説明します。