Techno Barje

JSctypes Round Two

Jsctypes has been introduced in Firefox 3.6 with simple C function call and only simple types: int, char, string, … But the next iteration of jsctypes that is coming in Firefox 4 is going to allow full C binding, with support of C structures and the ability to define a javascript function and give it to C library as a function pointer.

No more compilation, no more mozilla sdk download, nor XPCOM stuff, just plain javascript and only a tiny part of function and datatype declaration before doing a native binding!

But let the code talk! Here is an example that display a tray icon on windows. You can copy and paste this code in your Javascript Console in Firefox 4 beta, just do not forget to change the icon path defined in the loadimage function call.

  /* simply load "ctypes" object */
  /* Load libraries that we are going to use */
  var libuser32 ="user32.dll");
  var libshell32 ="shell32.dll");

  /* Here is the tedious work of declaring functions arguments types and struct attributes types */
  /* In fact it's quite easy, you just have to find which precise type are using your native functions/struct */
  /* but it may be hard to known, for example in windows API, which precise type is behing their "HANDLE" type ... */
  /* I recommend you to find and look at python ctype binding source code because they already had done this work */
    __in_opt  HINSTANCE hinst,
    __in      LPCTSTR lpszName,
    __in      UINT uType,
    __in      int cxDesired,
    __in      int cyDesired,
    __in      UINT fuLoad
  var loadimage = libuser32.declare("LoadImageA",
  const LR_LOADFROMFILE = 16;
  const IMAGE_ICON = 1;
  var notificationdata = ctypes.StructType("NOTIFICATIONDATA",
                                [{ cbSize  :          },
                                 { hWnd    :          },
                                 { uID     :          },
                                 { uFlags  :          },
                                 { uCallbackMessage : },
                                 { hIcon        :     },
                                 { szTip        : ctypes.char.array(64) },
                                 { dwState      :     },
                                 { dwStateMask  :     },
                                 { szInfo       : ctypes.char.array(256) },
                                 { uTimeoutOrVersion : },
                                 { szInfoTitle  : ctypes.char.array(64) },
                                 { dwInfoFlags  : },
                                 { guidItem     : },
                                 { hBalloonIcon : }
  const NIF_ICON = 0x00000002;
  BOOL Shell_NotifyIcon(
    __in  DWORD dwMessage,
    __in  PNOTIFYICONDATA lpdata
  var notifyicon = libshell32.declare("Shell_NotifyIcon",
  const NIM_ADD = 0x00000000;

  /* And now, the "real" code that is calling C functions */

  /* load our ico file */
  var hIcon = loadimage(0, "c:\\default.ico", IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
  /* create a C struct that is defining a notification in tray */
  var icon = notificationdata();
  icon.cbSize = notificationdata.size;
  icon.uFlags = NIF_ICON;
  icon.szTip = "My Tray Icon";
  icon.hIcon = hIcon;
  /* Display this notification! */
  notifyicon(NIM_ADD, icon.address());

We will be able to go futher and define a function callback to handle click events on the trayicon, but there is currently a bug which cause some crashes when using ctypes.FunctionType on windows. (ctypes.FunctionType allow to transform a custom Javascript function to a C function pointer)
Here is related bugs, which are still in process:

The first leads to crashes with FunctionType, and the second may lead to lib.declare with unfindable symbols errors when using ctypes.stdcall_abi.