JSctypes

From MozillaWiki
Revision as of 23:28, 2 March 2008 by MarkFinkle (talk | contribs) (update page to actual js-ctype content)
Jump to navigation Jump to search

Overview

js-ctypes is a foreign-function library for Mozilla’s privileged JavaScript. It provides C-compatible data types and allows JS code to call functions in shared libraries (dll, so, dylib) and implement callback functions. The interface and implementation are modeled on the Python ctypes module.

The main objective for the library is to help developers avoid building binary (C++) XPCOM components when only a simple wrapper is needed. Such situations include:

  1. Developer wants functionality not built into the Mozilla platform, but easily supported by the native OS.
  2. Developer wants to use a 3rd party library in an extension or XUL app.
  3. Developer has methods in native code for performance reasons.

The usual answer to these problems is creating a binary (C++) component to act as a wrapper so the native features can be exposed to JavaScript via XPCOM. However, the process of building binary XPCOM components is significantly harder than JavaScript components. The macros and memory management rules of binary components are harder than JavaScript, but its really the compiler and linker flags, IDL, makefiles and SDK versioning that make the process painful. The build process must be repeated for each platform too. For many cases, its just too much work.

The goal of js-ctypes is to allow developers to declare methods in binary libraries and then expose those methods as callable JavaScript functions. Developers can then create pure JavaScript library wrappers around binary libraries - without making binary XPCOM wrappers.

Example Usage

const nsINativeTypes = Components.interfaces.nsINativeTypes;
const MB_OK = 3;
 
function messageBox() {
  // create the XPCOM js-ctypes instance
  var library = Components.classes["@developer.mozilla.org/js-ctypes;1"]
                          .createInstance(nsINativeTypes);

  // load the native shared library
  library.open("user32.dll");

  // declare the native method
  var msgBox = library.declare("MessageBoxW",           /* function name */
                               nsINativeTypes.STDCALL,  /* call type */
                               nsINativeTypes.INT32,    /* return type */
                               nsINativeTypes.INT32,    /* arg 1 */
                               nsINativeTypes.WSTRING,  /* arg 2 */
                               nsINativeTypes.WSTRING,  /* arg 3 */
                               nsINativeTypes.INT32);   /* arg 4 */

  // call the native method
  var ret = msgBox(0, "This is the coolest message", "My Title", MB_OK);

  // test the return value
  alert(ret);
}

The js-ctypes code uses the same libffi library as the Python ctypes module. It is currently known to work on Windows and Linux. We need to start the Mac implementation. We also need to add support for struct and more primitive types.

The code is in SVN here and we have a Bugzilla component too (see bugs, file bug).

Note: This functionality cannot be accessed from JavaScript used in web content. Only JavaScript that runs with chrome privileges (extensions and Firefox UI for example) can use js-ctypes.