Haxe with external C

This example does not need NME but is useful if you do want to mix your own c++ with NME for a more general treatment see :CFFI tutorial

First lets create a default simple NME project and check that works fine, I am using rect to create a blue square to show that something is working. ( name the file Main.hx )

package ;

import nme.display.Sprite;
import nme.Lib;

using Main;
class Main extends Sprite 
{
    
    public static function main ()
    { 
        Lib.create(
                    function():Void
                    {
                        nme.Lib.current.addChild(new Main());
                    }, 
                    800, 600, 30, 0xFFFFFF, 
                    nme.Lib.RESIZABLE, "Test"
        );
    }
    
    
    public function new () 
    {    
        
        super ();
        
        // draw blue square so we can see something is happening.
        var sp = new Sprite();
        sp.rect( 0x0000ff, 100, 100, 100, 100 );
        addChild( sp );
        
    }
    
    public static function rect(     sp_:     Sprite
                                ,     c_:     Int
                                ,     x_:     Float
                                ,     y_:     Float
                                ,     w_:     Float
                                ,     h_:   Float
                                )
                                    
    {
        
        sp_.graphics.lineStyle( 0,0,0 );
        sp_.graphics.beginFill( c_, 1 );
        sp_.graphics.drawRect( x_, y_, w_, h_ );
        sp_.graphics.endFill();
        
    }

}

create a 'bin' directory for all the compiled files and next make the compile.hxml.
I am assuming we are using mac or linux, if you are on windows you will need to modify the last command.
-cpp bin
-main Main
-debug
-lib nme
--remap flash:nme
-cmd cd bin
-cmd ./Main-debug

Now if this works we can look at constructing some test c.
#define IMPLEMENT_API
#include <hx/CFFI.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
extern "C" { 
    value sum(value a, value b)
    {
    
        if( !val_is_int(a) || !val_is_int(b) ) return val_null;
        return alloc_int(val_int(a) + val_int(b)); 
    } 
}
DEFINE_PRIM( sum, 2 );

The first two lines give us access to special functions for conversion such as the alloc_int and val_int needed for c++ and neko to understand our c/c++ code, and the DEFINE_PRIM is there so Haxe can find the sum function. ( Save this file as Simple.cpp )


Next we need to add a line to compile our c/c++ code into a dynamic library. Also we need to make sure we include the special CFFI.h file, in this case I have created a subfolder called include and copied the include from the hxcpp haxelib include folder.
-cmd g++ -dynamiclib Simple.cpp -o bin/Simple.ndll -I./include
-cpp bin
-main Main
-debug
-lib nme
--remap flash:nme
-cmd cd bin
-cmd ./Main-debug

Now when you compile you should get a file generated called Simple.so.
Next we need to create a class in Haxe to deal with the C code, first I create a subfolder called 'wrapper' and then create this file.
package wrapper;

#if cpp
import cpp.Lib;
import cpp.Sys;
#elseif neko
import neko.Lib;
import neko.Sys;
#end

class WrapSum
{
    
    static var sum = Lib.load( Sys.getCwd() + "Simple", 'sum', 2 );
    public static function doSum( a: Int, b: Int )
    {
        
        return sum( a, b );
        
    }
    

    
}

and we can now update the Main class to use this function, first we comment out the actual line calling the Static method and just see if haxe is happy with the WrapSum class.
package ;

import nme.display.Sprite;
import nme.Lib;
import wrapper.WrapSum;

using Main;
class Main extends Sprite 
{
    
    public static function main ()
    { 
        Lib.create(
                    function():Void
                    {
                        nme.Lib.current.addChild(new Main());
                    }, 
                    800, 600, 30, 0xFFFFFF, 
                    nme.Lib.RESIZABLE, "Test"
        );
    }
    
    
    public function new () 
    {    
        
        super ();
        
        // draw blue square so we can see something is happening.
        var sp = new Sprite();
        sp.rect( 0x0000ff, 100, 100, 100, 100 );
        addChild( sp );
        
        trace( WrapSum.doSum( 10, 10 ) );
        
    }
    
    public static function rect(     sp_:     Sprite
                                ,     c_:     Int
                                ,     x_:     Float
                                ,     y_:     Float
                                ,     w_:     Float
                                ,     h_:        Float
                                )
                                    
    {
        
        sp_.graphics.lineStyle( 0,0,0 );
        sp_.graphics.beginFill( c_, 1 );
        sp_.graphics.drawRect( x_, y_, w_, h_ );
        sp_.graphics.endFill();
        
    }

}

version #15808, modified 2012-12-22 04:04:34 by vegetablesalad