compilation error with nativeGen on interface
Environment macos monterey 12.1 haxe 4.2.4 hxcpp 4.2.1
The error can be reproduced by compiling the following two modules for the cpp target.
//LogManager.hx
package log;
@:nativeGen
interface Logger {
function info(line: String): Void;
}
class LogManager {
public static function getLogger(): Logger {
return null;
}
}
//Client.hx
package log;
class Client {
static var logger = LogManager.getLogger();
}
The error reported is
Error: In file included from ./src/log/Client.cpp:1: In file included from /usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hxcpp.h:353: /usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/Dynamic.h:107:34: error: ambiguous conversion for functional-style cast from 'const Dynamic' to 'hx::Native<log::Logger *>' RETURN_ Cast() const { return RETURN_(*this); } ^~~~~~~~~~~~~ ./src/log/Client.cpp:53:55: note: in instantiation of function template specialization 'Dynamic::Cast<hx::Native<log::Logger >>' requested here if (HX_FIELD_EQ(inName,"logger") ) { logger=ioValue.Cast< ::hx::Native< log::Logger > >(); return true; } ^ /usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hx/Native.h:61:10: note: candidate constructor Native (const Native<T> &inNative) : ptr(inNative.ptr) { } ^ /usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hx/Native.h:63:10: note: candidate constructor Native (const cpp::Variant &inVariant) { ^ 1 error generated.
If the metadata @:nativeGen is removed from the interface Logger, the compilation works fine. But I need it because the interface is part of a library for which the end-users will provide a concrete implementation.
Hello!
Try to put @:unreflective meta on your Client class like:
//Client.hx
package log;
@:unreflective
class Client {
static var logger = LogManager.getLogger();
}
Thank you, now it works. But what is the meaning of the metadata? I can’t find any documentation about it.
Nice to hear it works!
It removes all that Dynamic stuff from your generated classes or methods. Basically, it removes reflection support.
But maybe there are more hidden things under the hood, I'm not sure :)
Unfortunately the trick of adding the metadata @:unreflective doesn’t seem to work in every circumstance.
For example the following trivial code is not affected by it.
package foo;
@:nativeGen
interface IFoo {
function foo(): Void;
}
class Main {
static function getList(): Array<IFoo> {
return [];
}
}
The reported error is
haxelib run hxcpp Build.xml haxe -Dhaxe="4.2.4" -Dhaxe3="1" -Dhaxe4="1" -Dhaxe_ver="4.204" -Dhxcpp_api_level="400" -Dhxcpp_smart_strings="1" -Dsource_header="Generated by Haxe 4.2.4" -Dstatic="1" -Dtarget.name="cpp" -Dtarget.static="true" -Dtarget.sys="true" -Dtarget.threaded="true" -Dtarget.unicode="true" -Dtarget.utf16="true" -Dutf16="1" -I"" -I"/usr/local/lib/haxe/std/cpp/_std/" -I"/usr/local/lib/haxe/std/"
Creating /Users/foo/temp/bin/cpp/obj/darwin64/__pch/haxe/hxcpp.h.gch...
Compiling group: haxe
g++ -Iinclude -c -fvisibility=hidden -stdlib=libc++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.1.sdk -O2 -I/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include -DHX_MACOS -m64 -Wno-parentheses -Wno-unused-value -Wno-format-extra-args -Wno-overflow -DHXCPP_M64 -DHXCPP_VISIT_ALLOCS(haxe) -DHX_SMART_STRINGS(haxe) -DHXCPP_API_LEVEL=400(haxe) ... tags=[haxe,static]
- src/foo/Main.cpp
Error: In file included from ./src/foo/Main.cpp:1:
In file included from /usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hxcpp.h:359:
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hx/Anon.h:236:42: error: no viable conversion from returned value of type 'hx::Native<foo::IFoo *>' to function return type 'hx::Val' (aka 'cpp::Variant')
if (inField.__s==name1.__s) return t1;
^~
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hx/Anon.h:222:37: note: in instantiation of member function 'hx::AnonStruct2_obj<int, hx::Native<foo::IFoo *>>::__Field' requested here
AnonStruct2_obj *result = new AnonStruct2_obj;
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hx/Operators.h:440:37: note: in instantiation of member function 'hx::AnonStruct2_obj<int, hx::Native<foo::IFoo *>>::Create' requested here
hx::AnonStruct2_obj< int,TO >::Create(HX_("key",9f,89,51,00),p,
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/Array.h:103:4: note: in instantiation of member function 'hx::ArrayKeyValueIterator<hx::Native<foo::IFoo *>, hx::Native<foo::IFoo *>>::next' requested here
ArrayKeyValueIterator(Array<FROM> inArray) : mArray(inArray), mIdx(0) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/Array.h:856:44: note: in instantiation of member function 'hx::ArrayKeyValueIterator<hx::Native<foo::IFoo *>, hx::Native<foo::IFoo *>>::ArrayKeyValueIterator' requested here
Dynamic keyValueIterator() { return new hx::ArrayKeyValueIterator<ELEM_,ELEM_>(this); }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/Array.h:910:50: note: in instantiation of member function 'Array_obj<hx::Native<foo::IFoo *>>::keyValueIterator' requested here
virtual Dynamic __keyValueIterator() { return keyValueIterator(); }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/Array.h:505:4: note: in instantiation of member function 'Array_obj<hx::Native<foo::IFoo *>>::__keyValueIterator' requested here
Array_obj(int inSize,int inReserve) :
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/Array.h:1142:29: note: in instantiation of member function 'Array_obj<hx::Native<foo::IFoo *>>::Array_obj' requested here
{ return Array<ELEM_>(new Array_obj(inSize,inReserve)); }
^
./src/foo/Main.cpp:32:65: note: in instantiation of member function 'Array_obj<hx::Native<foo::IFoo *>>::__new' requested here
HXDLIN( 16) return ::Array_obj< ::hx::Native< foo::IFoo* > >::__new(0);
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:21:11: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'const cpp::Variant &' for 1st argument
struct Variant
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:21:11: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::Variant &&' for 1st argument
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:66:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'const null &' for 1st argument
inline Variant(const null &) : type(typeObject), valObject(0) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:67:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'bool' for 1st argument
inline Variant(bool inValue) : type(typeBool), valBool(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:68:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'double' for 1st argument
inline Variant(double inValue) : type(typeDouble), valDouble(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:71:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::Int64' (aka 'long long') for 1st argument
inline Variant(cpp::Int64 inValue) : type(typeInt64), valInt64(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:72:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::UInt64' (aka 'unsigned long long') for 1st argument
inline Variant(cpp::UInt64 inValue) : type(typeInt64), valInt64(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:73:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'int' for 1st argument
inline Variant(int inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:74:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::UInt32' (aka 'unsigned int') for 1st argument
inline Variant(cpp::UInt32 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:75:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::Int16' (aka 'short') for 1st argument
inline Variant(cpp::Int16 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:76:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::UInt16' (aka 'unsigned short') for 1st argument
inline Variant(cpp::UInt16 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:77:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::Int8' (aka 'signed char') for 1st argument
inline Variant(cpp::Int8 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:78:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::UInt8' (aka 'unsigned char') for 1st argument
inline Variant(cpp::UInt8 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:89:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'hx::Object *' for 1st argument
inline Variant(hx::Object *inValue) : type(typeObject), valObject(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:310:13: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'const ::String &' for 1st argument
Variant::Variant(const ::String &inValue) :
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:313:13: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'const Dynamic &' for 1st argument
Variant::Variant(const Dynamic &inRHS) : type(typeObject), valObject(inRHS.mPtr) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:316:13: note: candidate template ignored: could not match 'ObjectPtr' against 'Native'
Variant::Variant(const hx::ObjectPtr<SOURCE_> &inObjectPtr) :
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:92:23: note: explicit constructor is not a candidate
explicit inline Variant(const cpp::Struct<T,H> &inVal);
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:94:23: note: explicit constructor is not a candidate
explicit inline Variant(const cpp::Pointer<T> &inRHS) ;
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:96:23: note: explicit constructor is not a candidate
explicit inline Variant(const cpp::Function<T> &inRHS) ;
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:98:23: note: explicit constructor is not a candidate
explicit inline Variant(const hx::Native<T> &inRHS) ;
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hx/Native.h:76:17: note: candidate function
inline operator T() const { return ptr; }
^
In file included from ./src/foo/Main.cpp:1:
In file included from /usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hxcpp.h:359:
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hx/Anon.h:244:48: error: no viable conversion from returned value of type 'hx::Native<foo::IFoo *>' to function return type 'hx::Val' (aka 'cpp::Variant')
if (HX_QSTR_EQ_AE(inField,name1)) return t1;
^~
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:21:11: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'const cpp::Variant &' for 1st argument
struct Variant
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:21:11: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::Variant &&' for 1st argument
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:66:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'const null &' for 1st argument
inline Variant(const null &) : type(typeObject), valObject(0) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:67:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'bool' for 1st argument
inline Variant(bool inValue) : type(typeBool), valBool(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:68:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'double' for 1st argument
inline Variant(double inValue) : type(typeDouble), valDouble(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:71:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::Int64' (aka 'long long') for 1st argument
inline Variant(cpp::Int64 inValue) : type(typeInt64), valInt64(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:72:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::UInt64' (aka 'unsigned long long') for 1st argument
inline Variant(cpp::UInt64 inValue) : type(typeInt64), valInt64(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:73:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'int' for 1st argument
inline Variant(int inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:74:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::UInt32' (aka 'unsigned int') for 1st argument
inline Variant(cpp::UInt32 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:75:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::Int16' (aka 'short') for 1st argument
inline Variant(cpp::Int16 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:76:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::UInt16' (aka 'unsigned short') for 1st argument
inline Variant(cpp::UInt16 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:77:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::Int8' (aka 'signed char') for 1st argument
inline Variant(cpp::Int8 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:78:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'cpp::UInt8' (aka 'unsigned char') for 1st argument
inline Variant(cpp::UInt8 inValue) : type(typeInt), valInt(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:89:14: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'hx::Object *' for 1st argument
inline Variant(hx::Object *inValue) : type(typeObject), valObject(inValue) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:310:13: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'const ::String &' for 1st argument
Variant::Variant(const ::String &inValue) :
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:313:13: note: candidate constructor not viable: no known conversion from 'hx::Native<foo::IFoo *>' to 'const Dynamic &' for 1st argument
Variant::Variant(const Dynamic &inRHS) : type(typeObject), valObject(inRHS.mPtr) { }
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:316:13: note: candidate template ignored: could not match 'ObjectPtr' against 'Native'
Variant::Variant(const hx::ObjectPtr<SOURCE_> &inObjectPtr) :
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:92:23: note: explicit constructor is not a candidate
explicit inline Variant(const cpp::Struct<T,H> &inVal);
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:94:23: note: explicit constructor is not a candidate
explicit inline Variant(const cpp::Pointer<T> &inRHS) ;
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:96:23: note: explicit constructor is not a candidate
explicit inline Variant(const cpp::Function<T> &inRHS) ;
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/cpp/Variant.h:98:23: note: explicit constructor is not a candidate
explicit inline Variant(const hx::Native<T> &inRHS) ;
^
/usr/local/Cellar/haxe/4.2.4/lib/haxe/lib/hxcpp/4,2,1/include/hx/Native.h:76:17: note: candidate function
inline operator T() const { return ptr; }
^
2 errors generated.
I assume that's because Haxe's Array<T> will work only with Haxe objects and will always be generated as ::Array< ::Dynamic>, so it can't cast IFoo to\from Dynamic type because IFoo is not really a Haxe object when you use @:nativeGen on it.
As I know there was a way to write your own Dynamic containers, or something like that, for any custom type, but I don't know how to do it exactly, sorry. Probably you need to look into sources, maybe you will find something.
But as a workaround you could try to wrap your IFoo into something like this:
class FooWrapper {
public final foo:IFoo;
public function new(foo:IFoo) {
this.foo = foo;
}
}
So then you can use it in Haxe arrays as Array<FooWrapper>
Thank you Dmitry. Your explanations are very useful.
I'm not sure, but I remember haxe not allowing you to assign class level vars to null, it might also be why you're crashing - ita not an intended behavior