Alchemy でポインタを扱う

Alchemy は malloc にも対応している。malloc で確保したメモリのポインタを AS3 側に伝えるのも簡単だ。

C 側の実装例

C で malloc した場所を AS3 に渡してみる。

static AS3_Val myAlloc(void* self, AS3_Val args)
{
    // 確保した値の初期値を受け取る
    int v;
    AS3_ArrayValue(args, "IntType", &v);

    // malloc でメモリ確保
    int* p = (int*)malloc(sizeof(int));

    // 確保したメモリに初期値を代入する
    *p = v;

    // ポインタを返す
    return AS3_Ptr((void*)p);
}

static AS3_Val myGetPtr(void* self, AS3_Val args)
{
    // ポインタを受け取る
    int* p;
    AS3_ArrayValue(args, "PtrType", &p);

    // ポインタが指す値を返す
    return AS3_Int(*p);
}

AS3_Ptr, PtrType がキーワード。

ActionScript3 側の実装例

ポインタは uint で受け取れますよ。

var lib:CLibInit = new CLibInit();
var obj:Object = lib.init();

// メモリを確保する
var p:uint = obj.myAlloc(9999);

// ポインタを渡して中身を受け取る
var v:int  = obj.getPtr(p);

ヒープの実装方法は?

AS3 にはご存知の通りポインタの概念はないんだけど、どのように実現されてるんだろう。また、C 側では malloc で確保したメモリがヒープ上にあるように見えるはずなんだけど、これはいったいどのように実現されているんだろう。

答えは簡単。ByteArray でヒープがエミュレートされている。ポインタの値はヒープのオフセット+ByteArray の先頭から何バイト目かの値になるわけだ。

AS3 側から ByteArray でエミュレートされたメモリを直接参照するには、GLEByteArrayProvider.get() を実行すればよい。詳しくは Alchemy:Documentation:Developing with Alchemy:AS3 API - Adobe Labs にて。