    [NAME]
    ALL.misc.comparison.binding

    [TITLE]
    C/C++ Function Binding (Python, Lua)

    [DESCRIPTION]

    The followings are simple examples to demostrate the differences in building C/C++
    function bindings for Python, Lua and Dao.

    The main advantage of Dao for interfacing C/C++ functions is that, the C/C++ functions
    can be registered with Dao function signatures, so that Dao can guarantee that only
    parameters with correct types can be passed to the functions. This can save much
    boilerplate code and overheads for parameter type checking and conversion, as well as
    codes for error handling for incorrect parameters.

     0   Python

       1  #include <Python.h>
       2
       3  /* Function to be called from Python */
       4  static PyObject* py_MySum(PyObject* self, PyObject* args)
       5  {
       6      double x, y;
       7      PyArg_ParseTuple( args, "dd", &x, &y );
       8      return Py_BuildValue( "d", x + y );
       9  }
      10
      11  /* Bind Python function names to C function(s) */
      12  static PyMethodDef MyModule_Methods[] =
      13  {
      14      { "MySum", py_MySum, METH_VARARGS },
      15      { NULL, NULL }
      16  };
      17
      18  /* Module entry function: */
      19  void initMyModule()
      20  {
      21      (void) Py_InitModule("MyModule", MyModule_Methods);
      22  }

     0   Lua

       1  #define LUA_LIB
       2  #include "lua.h"
       3  #include "lauxlib.h"
       4
       5  static int lua_MySum(lua_State *L)
       6  {
       7      double x = luaL_checknumber(L, 1);
       8      double y = luaL_checknumber(L, 2);
       9      lua_pushnumber( L, x + y );
      10      return 1;
      11  }
      12
      13  static const luaL_reg myfuncs[] =
      14  {
      15      { "MySum", lua_MySum },
      16      { NULL, NULL }
      17  };
      18
      19  /* Module entry function: */
      20  LUALIB_API int luaopen_MyModule( lua_State *L )
      21  {
      22      luaL_register( L, "MyModule", myfuncs );
      23      return 1;
      24  }

     0   Dao

       1  #include "dao.h"
       2  #include "daoValue.h"
       3
       4  static void dao_MySum( DaoProcess *proc, DaoValue *pars[], int npar )
       5  {
       6      /*
       7      // No need to check parameter types here, they are guaranteed to be
       8      // two doubles when this function is registered as:
       9      //   MySum( x : double, y : double ) => double
      10      //
      11      // So the parameter values can be retrieved directly if "daoValue.h"
      12      // has been included, otherwise, one may use "DaoValue_TryGetDouble()".
      13      */
      14      double x = pars[0]->xDouble.value;
      15      double y = pars[1]->xDouble.value;
      16      DaoProcess_PutDouble( proc, x + y );
      17  }
      18
      19  static const DaoFuncItem myfuncs[] =
      20  {
      21      /* A function signature must be provided for each function: */
      22      { dao_MySum, "MySum( x : double, y : double ) => double" },
      23      { NULL, NULL }
      24  };
      25
      26  /* Module entry function: */
      27  DAO_DLL int DaoMyModule_OnLoad( DaoVmSpace *vmSpace, DaoNamespace *ns )
      28  {
      29      DaoNamespace_WrapFunctions( ns, myfuncs );
      30      return 0;
      31  }