# Wrap C library in haxecpp?

**URL:** <https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486>\
**Category:** Haxe\
**Tags:** haxe-cpp\
**Created:** [May 29, 2020, 10:14am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486 "2020-05-29T10:14:58Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 29, 2020, 10:14am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/1 "2020-05-29T10:14:59Z")

</div>

Hello,

I am currently porting Haxe to Nintendo Switch homebrew (devkitA64), using hxcpp. I was able to run a hello world, and now I would like to write a small wrapper for the Switch homebrew C library libnx.

I started simple with a simple function: consoleInit(). For that, I wrote a Console class : [package libnx;import cpp.Star;@:native("PrintConsole")extern class Pri - Pastebin.com](https://pastebin.com/fQ3YPqKm)

However I feel like this is wrong - I should not have to duplicate the class in two. The thing is that the cppFileCode directive only works on top of “real” classes, and not extern ones, which is why I had to make two classes (consoleInit is in switch.h).

Any pointers? Is there a way to add project-wide includes to avoid that scenario?  
Thanks!

---

<div class="post-metadata">

**Author:** ![Aurel300](https://community.haxe.org/user_avatar/community.haxe.org/aurel300/32/72_2.png) [@Aurel300](https://community.haxe.org/u/Aurel300)\
**Post date:** [May 29, 2020, 10:25am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/2 "2020-05-29T10:25:48Z")

</div>

Not to sound like a broken record on this forum, but you could try with [ammer](https://github.com/Aurel300/ammer). 🙂

The process for defining ammer definitions is fairly simple – you need to map the C types to the Haxe types you want. For most common cases, there is a 1-to-1 mapping (e.g. `const char*` is a `String`). You can also define data types that map to library-specific types in C, like the `PrintConsole` in your code example.

For your library, the definition might looks something like:

```haxe
class Nx extends ammer.Library<"nx"> {
  // ...
}
@:ammer.struct // for alloc and free
class PrintConsole extends ammer.Pointer<"PrintConsole", Nx> {
  public function consoleInit(_:ammer.ffi.This):Void;
}

```

```haxe
class Main {
  public static function main():Void {
    var console = PrintConsole.alloc();
    console.consoleInit();
    // ...
  }
}

```

```haxe
-lib ammer
-D ammer.lib.nx.include=path/to/include/directory
-D ammer.lib.nx.library=path/to/lib/directory
-D ammer.lib.nx.headers=switch.h,nx.h,and_so_on.h
-main Main
-cpp out.cpp

```

(There is as of yet no way to create the type definitions automatically, since that would involve parsing the header files and essentially having a full C parser. Maybe one day.)

The [manual](https://aurel300.github.io/ammer/) should hopefully provide enough information.

---

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 29, 2020, 10:36am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/3 "2020-05-29T10:36:34Z")

</div>

I should specify that the Switch platform can only run statically linked binaries, and there is no way to load code at runtime. Does ammer work in that case ? Because I see shared objects and dylib and such 😃

---

<div class="post-metadata">

**Author:** ![Aurel300](https://community.haxe.org/user_avatar/community.haxe.org/aurel300/32/72_2.png) [@Aurel300](https://community.haxe.org/u/Aurel300)\
**Post date:** [May 29, 2020, 10:40am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/4 "2020-05-29T10:40:48Z")

</div>

You should be in luck because on C++ I rely on the native compilation rather than dynamically-loaded FFI (like on HashLink and Lua). hxcpp links libraries dynamically by default, but I believe this is configurable. And in fact, I assume you must have already linked the library statically for your code example to work. Did you put a configuration flag in your build to make the linking static? Does the compiler toolchain for Switch do static linking only?

---

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 29, 2020, 10:43am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/5 "2020-05-29T10:43:39Z")

</div>

> Did you put a configuration flag in your build to make the linking static

Yes !

> Does the compiler toolchain for Switch do static linking only?

Yes, although I did not include the linking step in my nxhpp toolchain yet (because there are multiple steps and a custom linker script) - for now I output a libMain.a that I then link in a standard homebrew using the standard Makefile 🙈

The end goal is to get rid of that “wrapper” so that the Haxe toolchain produces everything.

Let me try Ammer, that looks sweet !

---

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 29, 2020, 10:53am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/6 "2020-05-29T10:53:35Z")

</div>

@Aurel300 the library is absolutely trying to link with -L, which does not work because aarch64-none-elf-ar does not support -L

How can I remove that?

---

<div class="post-metadata">

**Author:** ![Aurel300](https://community.haxe.org/user_avatar/community.haxe.org/aurel300/32/72_2.png) [@Aurel300](https://community.haxe.org/u/Aurel300)\
**Post date:** [May 29, 2020, 11:05am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/7 "2020-05-29T11:05:32Z")

</div>

The actual linking paths for C++ are specified [here](https://github.com/Aurel300/ammer/blob/master/src/ammer/patch/PatchCpp.hx#L30-L34). For now I think you should try to modify those to whatever you’d have in `Build.xml` if you were doing this manually. I _think_ just providing the full path to a `.a` file makes it link statically? The `-L` argument comes from the `libpath` directive. If the absolute path to `.a` is provided, I think that directive can be removed completely.

**Edit** : alternatively, you could let the build fail, then edit the produced `Build.xml` file directly and re-build using `haxelib hxcpp run Build.xml`.

---

<div class="post-metadata">

**Author:** ![Aidan63](https://community.haxe.org/user_avatar/community.haxe.org/aidan63/32/517_2.png) [@Aidan63](https://community.haxe.org/u/Aidan63)\
**Post date:** [May 29, 2020, 11:16am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/8 "2020-05-29T11:16:00Z")

</div>

You could use `@:include` on native classes to ensure the switch header file is included, so your example would look like this.

```haxe
@:include('switch.h')
@:native('PrintConsole')
extern class PrintConsole
{
	//
}

@:include('switch.h')
extern class ConsoleNative
{
	@:native('consoleInit')
	static function consoleInit(_console : cpp.Star<PrintConsole>)
}

class Console
{
	public static function init()
	{
		ConsoleNative.consoleInit(null);
	}
}

```

Also, is your hxcpp toolchain publically available? About a month ago I got hxcpp running on the psvita homebrew sdk and I’d love to see what changes were done to get it running on the switch!

---

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 29, 2020, 11:31am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/9 "2020-05-29T11:31:04Z")

</div>

> The `-L` argument comes from the `libpath` directive. If the absolute path to `.a` is provided, I think that directive can be removed completely.

Yeah I will add libnx at the toolchain level (in hxcpp directly). So I need to fork Ammer then, to remove that directive.

> alternatively, you could let the build fail, then edit the produced `Build.xml` file directly and re-build using `haxelib hxcpp run Build.xml` .

I really want to reduce the steps as much as possible, ideally run haxe --cpp -D libnx and have everything magically work (including linking step)

> You could use `@:include` on native classes to ensure the switch header file is included, so your example would look like this.

I tried that but it adds `#include "switch.h"`, which is wrong (it needs to be `#include <switch.h>`) (include path is added at toolchain level)

> Also, do your hxcpp toolchain publically available?

Not yet but I did very little changes - since devkitA64 is based on newlib, the linux toolchain with aarch64-none-elf prefix worked out of the box. The whole hxcpp standard library built without any change to the code, which is awesome

---

<div class="post-metadata">

**Author:** ![Aurel300](https://community.haxe.org/user_avatar/community.haxe.org/aurel300/32/72_2.png) [@Aurel300](https://community.haxe.org/u/Aurel300)\
**Post date:** [May 29, 2020, 11:35am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/10 "2020-05-29T11:35:18Z")

</div>

> So I need to fork Ammer then, to remove that directive.

I assume you got ammer via `haxelib git` or `git clone`, so the change should be easy to make locally. I do actually want static linking support in ammer, I just haven’t had a need for it yet. So if the `.a` thing works in your project, I’ll add some configuration flags to make it painless. (Something like `-D ammer.lib.nx.link=static`, and maybe an extra path to the `.a` object, if the naming is not consistent.)

---

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 29, 2020, 11:43am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/11 "2020-05-29T11:43:22Z")

</div>

Yeah I’ll do that 👍

Does Ammer support C++ classes as well? I have a C++ library that I want to bind. I know I can do it using “extern” but if I can be consistent in the project and use the same mechanism for everything (libnx + my library) that would be great

---

<div class="post-metadata">

**Author:** ![Aurel300](https://community.haxe.org/user_avatar/community.haxe.org/aurel300/32/72_2.png) [@Aurel300](https://community.haxe.org/u/Aurel300)\
**Post date:** [May 29, 2020, 11:46am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/12 "2020-05-29T11:46:49Z")

</div>

Yes, although I haven’t tested it very thoroughly. In the test suite I just use some template instantiations ([C++ side](https://github.com/Aurel300/ammer/blob/master/tests/native/templates.cpp) and [ammer side](https://github.com/Aurel300/ammer/blob/master/tests/Templates.hx)). You can specify that a library is meant to be C++ with `-D ammer.lib.thelibname.abi=cpp`. Please report any issues you find!

---

<div class="post-metadata">

**Author:** ![Aidan63](https://community.haxe.org/user_avatar/community.haxe.org/aidan63/32/517_2.png) [@Aidan63](https://community.haxe.org/u/Aidan63)\
**Post date:** [May 29, 2020, 11:50am UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/13 "2020-05-29T11:50:15Z")

</div>

Thats good to hear. The vita’s SDK also provides a newlib and pthreads libraries but they don’t work that great / aren’t complete. Had to do a fair bit of commenting and stubbing out to get it to compile and not crash on startup.

---

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 29, 2020, 12:34pm UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/14 "2020-05-29T12:34:26Z")

</div>

I was able to remove the bad AR arguments by removing the directives in PatchCpp.hx. It’s kinda hacky but it does the job in the meantime.

Now it fails when linking because it doesn’t find w\_init in Console.cpp. That function is in ammer\_nx.cpp. It looks like that file is not included in the final libMain.a, any idea why?

---

<div class="post-metadata">

**Author:** ![Aurel300](https://community.haxe.org/user_avatar/community.haxe.org/aurel300/32/72_2.png) [@Aurel300](https://community.haxe.org/u/Aurel300)\
**Post date:** [May 29, 2020, 2:09pm UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/15 "2020-05-29T14:09:18Z")

</div>

Hmm, that’s strange. I can’t reproduce the error on OS X, even with a statically-linked C++ library. I assume `Console` is the name of the library/class you are using to define it? And it has a method called `init`? Couple of things to check:

- Does the generated `Console.cpp` reference one of the `ammer/externs/....h` files?
- Does the cpp file corresponding to that header file (i.e. `src/ammer/externs/....cpp`) in turn have something like `#define AMMER_CODE_0 #include "../ammer/ammer_native.cpp.c" #undef AMMER_CODE_0` ?

I am happy to help you debug, but maybe it’d be better to PM at this point, either over messages here or e.g. on Discord (Aurel300#1177).

---

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 29, 2020, 3:09pm UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/16 "2020-05-29T15:09:11Z")

</div>

I feel stupid now, it worked after a clean of the generated source code 🤦‍♂️

And the code runs on the console 🎉

I added you on Discord in case I have more questions

---

<div class="post-metadata">

**Author:** ![natinusala](https://community.haxe.org/user_avatar/community.haxe.org/natinusala/32/1236_2.png) [@natinusala](https://community.haxe.org/u/natinusala)\
**Post date:** [May 31, 2020, 4:24pm UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/17 "2020-05-31T16:24:39Z")

</div>

@Aidan63 the code is here if you want to see: [GitHub - retronx-team/switch-haxe: Switch Haxe sample project](https://github.com/retronx-team/switch-haxe) (link to the hxcpp fork in the readme)

---

<div class="post-metadata">

**Author:** ![Lelelo1](https://avatars.discourse-cdn.com/v2/letter/l/9f8e36/32.png) [@Lelelo1](https://community.haxe.org/u/Lelelo1)\
**Post date:** [August 22, 2021, 12:17pm UTC](https://community.haxe.org/t/wrap-c-library-in-haxecpp/2486/18 "2021-08-22T12:17:33Z")

</div>

How come any platform can’t be built to when Haxe uses a C dependency?
