I have a swig interface to a C++ member function that returns a std::vectorstd::string.
In lua I can do:
`local foo = thing:getStringArray();
for i = 0, foo:size()-1 do
print(foo[i]);
end`
In haxe I’m very close because foo[i] works so I can say
`extern class thing {
public function getStringArray() : Array<String>;
}`
var stuff = thing:getStringArray();
trace(stuff[3])
But the it feels wrong as there is no mapping of the lua vector length to the haxe Array size.
The haxe Vector/Array concepts seem inverted from C++ w.r.t. dynamic sizing.
Is the correct path to make a CStdStringVector class and extern stuff? (I think mapping the [] operator might cause me sadness though.)
Looks like
`@:native("__getitem__") @:op([]) public function arrayRead(n:Int) : String;`
// access to C++ std::vector<std::string> as wrapped in lua
extern class CVectorString {
private function new();
public function size(): Int;
public function __getitem__(n:Int) : String;
}
Is failing on the lua side with
Error in std::vector< std::string >::getitem (arg 2), expected ‘unsigned int’ got ‘string’
There’s a way forward here, but I’ll need some more details:
Generally lua externs for c libraries will wrap vector returns in a table. Is that not the case here? How do you get the vector size in pure lua code otherwise?
Regardless of how it’s returned, I believe you will need to use an abstract for the class here. You’ll need this to provide bracket access to the vector, and to “autocast” to a standard haxe Array so that it will work well with the rest of the Haxe std lib. There are some helper methods for this in TableTools and Boot.
I think it would be super helpful to get a small working example of the code you’re dealing with so I can give more precise suggestions.
I’ll try to pull out the swig/C++/lua layers.
Might take some time.
On the lua side, the std::vector std::string wrapper is overriding the getitemsetitem etc. in the metatable to call the C++ vector operations. This is nice because in lua if I do
local foo = getCStringVector()
print(foo[3])
it doesn’t matter if there are 3 or 300000 items in the vector, only one gets pulled out. It’s not so nice because lua does the stupid 1 base index, vs. the 0 base for everything else.
My current work around (because my vectors are small, worst case 200 strings) is to make a helper function and inline it for the method that would return the std::vector std::string and lump the copy.
class CVectorToArray {
@:generic
public static function convert<T>(vec:CVectorType<T>) : Array<T> {
var ans:Array<T> = [];
untyped __lua__("for i = 0,vec:size()-1 do ans[i] = vec[i] end");
return ans;
}
}
private function getCStringVector() : CVectorType<String>;
public inline function metricListArray() : Array<String> {
return CVectorToArray.convert(this.metricList());
}
The magic that lets the C++ through lua comes from line 52 of:
(And I know I’m an edge case, because why to haxe → lua → C++ instead of haxe → C++, but we distribute lua as the configuration language and load lua at runtime.)