Using native (C/C++) code

Hi all!

I know that with haxe one can use external native libraries,
but is there some nice way to write modules similar to traits in C++ or C for performance reasons?

http://armory3d.org/manual/#/code/wasm

I think that is about wasm, entirely different beast. I’m more here about using native code for native targets and wasm for web targets.

Armory is doing this currently for physics: When you’re targeting Linux, Windows or Mac, the bullet physics library (written in C) is used. When you’re targeting web, it uses Ammo.js.

And that’s pretty much all I know about this topic :slight_smile:. Maybe a starting point for more research could be here: http://old.haxe.org/doc/cpp/ffi

Waaah that doc is wacky… I better look at how Bullet is hooked in…

I cooked a set of minimal examples for Kha a while ago which should also come helpful.

Calling C++ from Haxe:

Creating C++ externs for a nicer integration:

Calling functions from .dll/.so:

Will add a topic on that to the manual…

4 Likes

I tried to follow those examples but could neither them nor anything else get running in Armory.
When exporting the project Haxe always fails with the following exceptions:

  1. kha_callcpp:
    Unbound identifier cpp

  2. kha_cppexterns:
    Extern type not supported : MyClass

2b) kha_cppexterns when trying to access the static function only:
Invalid_argument(“index out of bounds”)

Did anybody had success calling native C/C++ code?

Armory doesn’t use hxcpp anymore so that is probably why those examples didn’t work.

From the normal development build of Armory that is created when you run the game from Blender, there isn’t a way to call native C++ code. If the C++ library can be compiled to JavaScript with Emscripten, then it is possible to bind Haxe to that library’s JavaScript version during development, and then to bind it to native C/C++ for the production build. That is how the bindings for Bullet physics are handled.

If you wanted to call native C/C++ code from Armory’s development version, you would need to fork and re-compile Krom and add JavaScript bindings to the library in there.

If you need more clarification and I explain further. It would be good to know what your use-case is, too.

1 Like

Hey, thanks for pointing me in the right direction!
I spent some time today checking out your work but could not get Bullet running.

However I was able to write a simple app that uses native cpp code. You can find it here https://github.com/TheDoorNextBoy/myhl

If you have a look at hl/MyHl.cpp (which would be my version of the hl/bullet.cpp) you can see that I just created the methods myself. Can these be generated automatically?
I am not sure on how to use Emscripten / how the output of it would help me.

I am aware that you are working on a solution for Kha to support native C++, but it looks like this might take a while until it’s merged in and I need at least provide a proof of concept soon so I can’t really wait.

My current use-case is to use an external SDK for voice recognition which has different SDKs for JS, C++, Android, iOS. Also I want to be able to use platform specific features like receiving SMS on Android phones. So some functionality would be different and or not available on some platforms.

Let me know your thoughts :slight_smile:
If I am successful I am happy to provide some documentation or tutorials when done.

Yes they can. Those bindings you found actually were auto-generated by this line. The definition of the bindings is done with a WebIDL file that outlines the interface to the library.

The PR that I was working on will essentially just automate that process, but you can still manually use the WebIDL library to generate those HashLink bindings.

When you click “Play” in the Blender interface for an Armory game, it actually runs the game in a Javascript environment provided by Krom. The purpose for Emscripten would be to compile the C++ library to JavaScript so that you can use it in Krom. If the library you are using already has a JavaScript client, then you could create Haxe externs, like the ones here, for that JavaScript library but you would have to manually add some code in your game to make it load the JavaScript bindings ( it isn’t that hard ). You could also just forego making the library work in Krom if you just need it for the native builds.

For stuff like needing SMS support on Android and also if the voice recognition library is different on Android and iOS, you would probably have to make HashLink bindings to the native Android SDK in the same way that you do it for native libraries on desktops.

I’m not sure how easy all of that would be for your particular use-case, but I think that it should be able to work.

Hmm I am afraid I just could not get the WebIDL to run in the way I thought (not sure what to do with the sample provided for the library).

When / how did you create hl/bullet.cpp? I feel like this is the only part that I am missing. Is this created with Emscripten?

I thought everything should get generated automatically by webidl. I have a MyClass WebIDL file. The export from Armory to Android worked, but I couldn’t build it in Android Studio because my 2 methods were not resolved. So I looked them up and created the hl/MyHl.cpp manually.
The generated (but unresolved) method looks like this

HL_API int myhl_MyClass_testFunction0(vbyte*)

I am sure I will find a way for the different use-cases. Thanks for showing the different options I might use more than one way at the end but am optimistic already.

It isn’t created with emscripten. Check out this example of a simple use case. You need to set the HLPATH environment variable to the path to the src dir of the HashLink repo and then run make. It will create a libpoint.cpp file with the bindings in it in the same directory. You should be able to use the same setup to generate the bindings for your library.