Getting Started with Native Code

Monkey Archive Forums/Monkey Tutorials/Getting Started with Native Code

Tibit(Posted 2012) [#1]
Here is a quick simple tutorial for wrapping native functions!

SIMPLE html5 example - myDeviceResolution.monkey

Import "myNative.js"


Function SetDeviceResolution:Void(w:Int, h:Int)
'Add more functions here if you want

Public ' Back to Public from Extern

Import the file with native code. In this case I'm using a .js file then we will call a function in this file.

In file called myNative.js
function SetDeviceResolution(w, h) {
var canvas=document.getElementById( "GameCanvas" );
canvas.width = w;
canvas.height = h;

Anywhere in your code just import the monkey-file above

Then just call SetDeviceResolution( 500,400), and if you are on the html5 target that javascript function will be called with those parameters.

Explanation: Extern like Public and Private are used to switch access scope and can only be used outside a class (in module scope). Type Extern and now external functions can be defined as one-line abstract functions. Type Public, or Private to go back to normal definitions.

Function SetDeviceResolution:Void(w:Int, h:Int) automatically maps to the function SetDeviceResolution(w, h) in the myNative.js file because they have the EXACT same name.

You can be more fancy here and import depending on the file's name
Here is an example of that from diddy:

#if HOST="macos" And TARGET="glfw"
Import "native/diddy.${TARGET}.mac.${LANG}"
Import "native/diddy.${TARGET}.${LANG}"

Above: Note that in the import string ${LANG} will be replaced by cpp,js,cs,as or java AND ${TARGET} will be replaced by android, flash, html5, glfw,ios,psm,win8 or xna

For this to work on all targets you need to create 8 files, one per target! Also note that in diddy's case above they have 2x for the glfw due to slight changes in mac/win. Also the native/ means those files are expected to be placed in a folder called "native".

If you do not yet support one or more targets you can add something like this to your Monkey file:

#If LANG<>"js"
#Error "setting device resolution are unavailable on this target"

If you prefer to name your native functions different from the Monkey one then you might be happy to learn that Monkey also supports wrapping like this:

Function MySetDeviceResolution:Void(w:Int, h:Int) = "SetDeviceResolution"


Now "SetDeviceResolution" will be the function-name in the .js file that will be called.

Remember it is CaSEseNsitivE.

For more in-depth and advanced wrapping check this tutorial out:
iOS Integration

Armitage1982(Posted 2012) [#2]
This is exactly the kind of tutorials that should be available in the Monkey documentation.

An extended version for C#/C++ and the use of external libraries is more than welcome !

Sammy(Posted 2012) [#3]
An example of native C would be great for me too! :)

MikeHart(Posted 2012) [#4]
diddy and even my module have native cpp code integrated. So a quick look there shows you how it can be done. The problem are static libraries, These can't be imported automatically. You need to modify the created project to be able to use these.

Sammy(Posted 2012) [#5]
Hi Mike, thank for the tips.

What is the problem with static libs, is it including the libs in the build or is there a problem calling the lib?

AdamRedwoods(Posted 2012) [#6]
Including the lib into the compilation process is not allowed (yet). it would need a mod to the trans (see Monkey-Extra module) to allow CC_OPT style switches like "-lmylib".

slenkar(Posted 2013) [#7]
good tutorial m8