loading...

Hashlink Primes

amir_rezai profile image Amir Mohammad Rezai Updated on ・2 min read

Hashlink Primes (2 Part Series)

1) Hashlink Primes 2) C/Hashlink Pointers

When you want to migrate your code from C to Haxe the best way is to use Hashlink and it's primes.
Similar to NekoVM and it's primes, Haxe virtual machine -Hashlink- also has it's own primes and as I dive deep through it's hard only because there is no API documentation on it, even lesser than neko.

To convert C library to Haxe you have to write a medium in C and Haxe, easiest functions are to return a value and not a Hello World string.

I create a project directory and call it hashlink-prime-test.
Inside I will have a build.hxml:

-cp src
-hl out/hello.hl
-main Main

And a Makefile:

CFLAGS = -Wall -O3 -msse2 -mfpmath=sse -std=c11 -D LIBHL_EXPORTS -fPIC -shared

hello.hdll: lib/hello.c
    ${CC} ${CFLAGS} -o hello.hdll lib/hello.c -lhl

If you have worked with Haxe before, by looking at hxml you will know that there is a Main.hx file reside inside src directory, which is out source start point.

And also if you look at the makefile you can realize there is a directory lib and a hello.c source inside it which contains our Prime functions.

First we will review the C source code then we will delve into Haxe class.

#include <hl.h>

HL_PRIM bool hl_is_true() {
    return true;
}
DEFINE_PRIM(_BOOL, is_true, _NO_ARG);

We have to include hl.h header file so we can use Hashlink Primes.

A hashlink prime function is defined using HL_PRIM, then function return type is specified in this case bool (is not standard C type is defined in hl.h) and function name prefixed with hl_.

The function body is self explanatory and at last we have to export this prime using DEFINE_PRIM.

DEFINE_PRIM macro takes 3 arguments:
1) Function Return Type.
2) Function
3_ Function Arguments. (_NO_ARG = no argument, and multiple argument are space seperated.)

this will define how the function should look in Haxe.

This function turns into: isTrue() function when using in Haxe but we have to define it using @:hlNative("hello")

hello is the name of hdll file as we compiled it in Makefile: ${CC} ${CFLAGS} -o hello.hdll lib/hello.c -lhl

You might want to write a Hello.hx class to use that function but I have written it inside Main.hx as another class note that you have to specify it's external class using extern keyword:

package;

class Main {
    static function main() {
        trace( Hello.isTrue() );
    }
}

@:hlNative("hello")
extern class Hello {
    public static function isTrue():Bool;
}

This shall work when you run it using hashlink.

I still couldn't find the right time to compile a string in C since _STRING type is a bit complicated but I have been able to use hashlink Bytes type to output a "Hello Hashlink." from C.

#include <hl.h>

HL_PRIM vbyte* hl_say_hello() {
    const char * str = "Hello Hashlink.";
    return (vbyte*)str;
}

DEFINE_PRIM(_BYTES, say_hello, _NO_ARG);
package;

import hl.Bytes;

class Main {
    static function main() {
        trace(@:privateAccess String.fromUTF8(Hello.sayHello()));
    }
}

@:hlNative("hello")
extern class Hello {
    public static function sayHello():Bytes;
}

Hashlink Primes (2 Part Series)

1) Hashlink Primes 2) C/Hashlink Pointers

Posted on by:

amir_rezai profile

Amir Mohammad Rezai

@amir_rezai

I'm a game developer, with performance issues in mind. Live in Nerverland, Iran.

Discussion

markdown guide