必要条件
この記事に必要な予備知識
この記事を最大限活用するには、ActionScript、C言語、Flash Builder、Xcodeを十分に理解し、コマンドラインからのツールが使用できる必要があります。
必要なその他の製品(サードパーティ/ラボ/オープンソース)
ユーザーレベル
中級
このシリーズのパート1では、iOSでのネイティブ拡張機能を使用して、Number、int、uint、String、Booleanなどの基本データ型をActionScript 3とC(またはC++、C#、Objective-C)間で交換する方法を紹介しました。この記事では、ArrayオブジェクトとVectorオブジェクトを使用した同じ技法について解説します。
パート1をまだ読んでいない場合は、この記事を読み進める前にパート1を読むことをお勧めします。
この例では、ネイティブ言語のreverseArray()
関数を実装しています。この関数は、ActionScriptのArrayオブジェクトの要素の順序を逆にします。例えば、[1,2,3]
という配列を与えると、[3,2,1]
を返します。
ActionScript 3のコードを次に示します。
public function reverseArray(array:Array):Array{
var ret:Array= context.call("reverseArray",array) as Array;
return ret;
}
このCコードは基本データ型のコードよりも少し複雑です。このCコードでは次の手順を実行します。
- 引数から配列を取得します。
- 配列の長さを見つけます。
- C言語でActionScript 3の新しいArrayインスタンスを作成します。
- 元の配列をループして、新しい配列に値をセットします。
- 新しい配列を返します。
コードは次のとおりです。
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;
}
Vector変数を交換するための実装方法は、Array変数を交換するための実装方法とほぼ同じです。主な違いは、Vectorオブジェクトの作成方法です。整数の要素を持つVectorの場合は、次のようになります。
FRENewObject((const uint8_t*)"Vector.<int>", 0, NULL, &populatedArray, nil);
ここに、reverseVector
のActionScript 3コードを示します。このコードは、reverseArray
と同じ機能を実装しています。
public function reverseVector(vector:Vector.<int>):Vector.<int>{
var ret:Vector.<int>= context.call("reverseVector",vector) as Vector.<int>;
return ret;
}
Cコードは次のとおりです。
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;
}
パート1で述べたように、ネイティブ拡張機能について、さらに詳しく学びたい場合は、Adobe AIR拡張機能向けの「ネイティブ C API リファレンス」を参照することをお勧めします。
このシリーズのパート3(間もなく公開)では、ActionScript 3とネイティブ拡張機能間でのカスタムオブジェクトの交換を扱います。