COMMUNITY

Passing a string array from Haxe to C++

I have a C function with a signature similar to

int my_function(int argc, const char **argv)

I have created extern definition as

@:native("my_function")
public static function myFunction(argc: Int, argv: RawPointer<ConstCharStar>): Int;

How do I pass it an array like
var args = ["abc", "xyz, "pqr"];

You can use cpp.Pointer to get the address off the first element in the array. So something like this.

myFunction(args.length, Pointer.arrayElem(args, 0).raw);

You can see all of the useful functions the pointer class has at https://api.haxe.org/cpp/Pointer.html

I tried this

var args = [ "abc", "xyz"];
C.myFunction(args.length, Pointer.arrayElem(args, 0).raw);

But of course it doesn’t accept String. I tried cast but it fails with no known conversion from String * to 'const char **

So I tried this

using NativeString;
var args: Array<ConstCharStar>  = [ConstCharStar.fromString("abc"), ConstCharStar.fromString("xyz")];
C.myFunction(args.length, Pointer.arrayElem(args, 0).raw);

Now I get more errors

/usr/local/lib/haxe/lib/hxcpp/4,0,8/include/Array.h:497:30: error: assigning to 'const char *' from incompatible type 'Dynamic'
/usr/local/lib/haxe/lib/hxcpp/4,0,8/include/Array.h:1004:40: error: no viable conversion from 'Dynamic' to 'const char *'
/usr/local/lib/haxe/lib/hxcpp/4,0,8/include/Array.h:886:65: error: cannot cast from type 'const cpp::Variant' to pointer type 'const char *'

And so on.

ah yeah, sorry, I completely skipped over that. Unfortunately hxcpp arrays don’t work with Pointer or RawPointer types so your fromString approach won’t work. What I usually do in situations like this is create an extern around std::vector and use that. For example.

var args = StdVectorString.create();
args.push_back('hello');
args.push_back('world');

myFunction(args.size(), args.data());

Where StdVectorString is the following extern.

@:keep
@:unreflective
@:structAccess
@:include('vector')
@:native('std::vector<const char*>')
extern class StdVectorString
{
    @:native('std::vector<const char*>')
    static function create() : StdVectorString;

    function push_back(_string : ConstCharStar) : Void;

    function data() : RawPointer<ConstCharStar>;

    function size() : Int;
}

By no means the most elegant or convenient solution, but I just put together a small test and it works fine.

1 Like

Sort of a roundabout way but it works. Many thanks.

Two cents: you can convert haxe String to const char* with haxeString.c_str() on cpp side.

In any case, this is a situation where I’d really want to see A BIG FAT COMMENT in the source-code as well as in the project documentation, calling everyone’s attention to the issue and to exactly how you solved it – since such things could be considered “fragile.” Give the rest of the team, both present and future, a very big “heads up.” Forewarned is forearmed. Next time someone touches this code, or needs to do something similar, they’ll know to be on their tiptoes … or pick up a “lesson learned.”