aka larsbounty#2.
I’ve just seen it got bumped again, so I kinda forced to report. I didn’t really want to do that because I wasn’t sure if anything will come out of this (I’m still not sure). But here it is.
Idea is to convert this
@:hlNative( 'lib' )
class A {
function b( x:String, y:Int ):String;
}
to this (for hl):
class A {
static inline public function b( x:String, y:Int ):String {
return @:privateAccess String.fromUtf8( b_wrap( x.toUft8(), y ) );
}
@:hlNative( 'hxlib', 'b_wrap' )
static public function b_wrap( x:hlBytes, y:Int ):hl.Bytes {
return null;
}
}
or this (for hxcpp):
class A {
static public var b:(String,Int)->String = cpp.Lib.load( 'hxlib', 'b_wrap', 2 );
}
Or something like that. Also, appropriate cpp file gets generated and compiled into ndll or hdll.
What works:
- it compiles and runs on hxcpp
- you can pass Ints, Floats, and Strings and have them returned back
- examples that are required in original bounty do (kind of) work (maybe)
What does not work (aka strings are tricky):
- if you have a c api of type void concat( const char *x, const char * y, char * result ); then you’ll have to write the code that explicitly allocates new string, gets the pointer, calls this function and returns the result.
- api that allocates memory and returns it will leak (trying to figure out how to allocate finalizers without copying everything).
- if api requires you to pass allocated memory then you have to convert haxe.io.Bytes to memory pointer on the c side explicitly (it can be made automatic but it is as it is for now).
- all this fiddling on hl target with to/from utf8. It is (should be) slow, but more than that it does not work. For example, on windows everything that is not ascii is (I believe) in ucs2. So if wrapped library uses unicode then it will most likely crash. And even for non-unicode appfunctions it will only work for lower part of ascii table.
- c++ compilation is tricky. For now there is no way to add libraries, header file paths, flags etc to build.xml, because I’ve no idea how to do that (more metadata, most likely). Regarding hl I don’t even know how I should compile.
- the whole api is ad-hoc and I’m not sure if it will be usable for something bigger than this example.
- hl build should still crash at runtime.
Right now api looks like this: https://pastebin.com/dYk59e3b
And generated hxcpp code looks like this: https://pastebin.com/zVVN86Xm
And its output (lines do not match because I’ve cleaned some comments):
If someone has any suggestions (especially about how to convert does not work into works) or sees what that I do does not make sense then please tell.
Also, as you may see, stringConcat2 should return “test123” but it returns true. This is because I return const char*, then hxcpp calls ToValue on result and there is no overload for ToValue( const char* ), so msvc decides that closest type to const char* is bool and here we go. I’m not fixing it because fix will leak memory anyway and if I fix memory leak this will work automatically.
Also, I think I may have broken something because even though add_nums_wrap receives ints and returns int, and it’s defined with DEFINE_PRIME, val_int is still called on both arguments and return value is passed to alloc_int. Pretty sure this is not intended because iirc performance was one promised feature of CFFIPrime over “standard” neko-inspired cffi.
FAQ:
Q: Code where?
A: I won’t share it at least before example starts to work out of the box, and I don’t have to compile libraries manually.
Q: Code when?
A: I’m really not sure. Not any time soon.
Q: Why not use @:native/@:nativeGen thing for hxcpp?
A: I would like to but 1. it does not look like it is easy to generate, and 2. I have no idea how it works.