How to use ArrayAccess for extern class?

I read in the Haxe API reference that ArrayAccess interface is used to indicate that an extern class supports array access. But it won’t work for me.

Sample code

import cpp.*;

@:unreflective
@:structAccess
@:include("array")
@:native("std::array<int, 10>")
extern class NativeIntArray implements ArrayAccess<Int> {
	public function size():SizeT;
	public function at(index:Int):Int;
	public function data():RawPointer<Int>;

	public static inline function create():NativeIntArray {
		return untyped __cpp__("{}");
	}
}


class Main {
	static function main() {
		var myArray = NativeIntArray.create();
		myArray[0] = 555;
		trace('The value at index 0 is ${myArray[0]}');
	}
}

The generated code for this is

void Main_obj::main(){
	 std::array<int, 10> myArray = {};
	( ( ::Dynamic)(( (cpp::Struct<  std::array<int, 10> >)(myArray) )) )->__SetItem(0,555);
	::haxe::Log_obj::trace((HX_("The value at index 0 is ",c9,66,be,b9) + ( ( ::Dynamic)(( (cpp::Struct<  std::array<int, 10> >)(myArray) )) )->__GetItem(0)),hx::SourceInfo(HX_("src/Main.hx",9a,7a,30,a1),21,HX_("Main",59,64,2f,33),HX_("main",39,38,56,48)));
}

I would have expected myArray[0] = 555. However it is creating a cpp::Struct instance, casting it to Dynamic and calling __SetItem on it instead. It doesn’t work either.

Is this a bug or am I doing something wrong?

I recently ran into this issue as well and don’t think hxcpp implements array access on extern classes, even if you explicitly tag properties with @:arrayAccess it still doesn’t work. You can work around this by creating an abstract over the native class. e.g.

@:forward()
private abstract IntArray(NativeIntArray)
{
    public function new()
    {
        this = NativeIntArray.create();
    }

    @:arrayAccess
    inline function arrayGet(_key : Int) : Int
    {
        return this.data()[_key];
    }

    @:arrayAccess
    inline function arraySet(_key : Int, _value : Int) : Int
    {
        this.data()[_key] = _value;

        return _value;
    }
}

Unfortunately it requires two definitions if you want array access on your extern class, but it will work.

2 Likes

Oh, I see. Thanks for the help.