Native Extension pass ByteArray from haxe to C++

Hey,

so I am trying to pass an openfl.utils.ByteArray to C++, that I want to fill with pixel data and then in openfl write that ByteArray back into openfl.display.BitmapData. I stumbled across this post, but that didnt get me far: http://www.openfl.org/archive/community/programming-haxe/how-to-send-bytearray-to-c-in-native-extension/

So on the haxe side I’ve got this:
pri

vate static var cpp_dosomething = Lib.load ("cpp_myextension", "cpp_dosomething", 1);
cpp_dosomething(buffer);

And on the cpp side this:

static void cpp_dosomething (cost char * pixelbuffer)
{
	// set pixel data in some way
	for(int i = 0; i < width * height; i++) {
		memset(pixelbuffer + i * 4, 0xff000000, sizeof(int));
	}
}
DEFINE_PRIM (cpp_dosomething, 1);

You can use bitmapData.image.buffer.data directly (but you have to be careful about premultiplied alpha and color order) or use the ByteArray APIs to have it handled for you

Either Float32Array or openfl.utils.ByteArray will be a derivative (in current version) of haxe.io.Bytes, this has a b field that has the real bytes and a length field that tells you the length.

Haxe objects passed to C++ come through as an opaque value type, which needs to be cast to the proper C++ types. For example:

static void cpp_dosomething (value pixelbuffer) {
    
    value b = val_field (pixelbuffer, val_id ("b"));
    int length = val_int (val_field (pixelbuffer, val_id ("length")));
    
}

That gives you a reference to the “b” field, and the length value. The tricky part on “b” is that it will be a raw string on Neko, and a buffer object on C++.

You can see some of how we do it here:

I think you can use val_to_buffer (b), and if !val_is_null (buffer) use that, otherwise, val_string (b) for Neko

Thank you so much for the extensive and quick answer! I will try that first thing in the morning and write up how that worked out for me!

Okay, just looked again. This might work:

static void cpp_dosomething (value pixelbuffer) {
    
    value b = val_field (pixelbuffer, val_id ("b"));
    if (val_is_null (b)) return;
    
    unsigned char* data = (unsigned char*)buffer_data (val_to_buffer (b));
    if (!data) data = (unsigned char*)val_string (b);
    
    int length = val_int (val_field (pixelbuffer, val_id ("length")));
    
    // do something with data pointer and length int value
    
}

Thanks a lot, passing a openfl.utils.ByteArray into singmajesty’s cpp_dosomething method worked just fine! But I didn’t manage to access and maniuplate bitmapData.image.buffer.data directly, which is the way I would want to do it ideally to reduce the overhead of having an extra buffer. As far as I understand the Type of bitmapData.image.buffer.data is lime/utils/UInt8Array. But I can’t just directly manipulate that, because it is not a uint8 array, but a hxpp object that has a little bit of extra information?

Oh, right, try uint8Array.buffer, or I think you can cast it like this:

var bytes:Bytes = bitmapData.image.buffer.data;

I think that will do the conversion for you as well