ctypes.open

At the heart of js-ctypes is the ctypes.open() function. This must be called before any work can commence. There are two options:

Custom native file

For this method, a native file must be created. A native file for use on UNIX systems is an SO file, which is created and a C function called add() is written.

int add(int a, int b) {
  return a + b;
}

To make this a shared library, a native file which can be loaded and used from js-ctypes, compile it with these commands:

gcc -fPIC -c myCFuntionsForUnix.c
gcc -shared -o myCFuntionsForUnix.so myCFuntionsForUnix.o

A file named myCFuntionsForUnix.so is successfully created. This native file can be placed in any folder of an addon and then loaded from js-ctypes. They can also be loaded from the system library path.

Loading the native file

If your addon is restartless, you must set it to be unpacked. See: http://stackoverflow.com/questions/19382201/how-to-load-dll-from-sdk-addon-data-folder

It is important to note that custom native files cannot be loaded through chrome:// or resource:// URIs. They must be accessed through a local file path  (file://) or a JAR path (jar:). If the addon is an unpacked addon, such as bootstrap or Add-on SDK addons, the JAR path must be used. Therefore, the path has to be converted and then the converted path is used for loading with ctypes.open.

If the native file is located at chrome://youraddon/content/mySubFolder/myCFunctionsForUnix.so then it is converted to a File URI like this:

Components.utils.import("resource://gre/modules/Services.jsm");
var cr = Components.classes['@mozilla.org/chrome/chrome-registry;1'].getService(Components.interfaces.nsIChromeRegistry);
var chromeURI_myLib = Services.io.newURI('chrome://youraddon/content/mySubFolder/myCFunctionsForUnix.so', 'UTF-8', null);
var localFile_myLib = cr.convertChromeURL(chromeURI_myLib);
var jarPath_myLib = localFile_myLib.spec; // "jar:file:///C:/Users/Vayeate/AppData/Roaming/Mozilla/Firefox/Profiles/aecgxse.Unnamed%20Profile%201/extensions/youraddon@jetpack.xpi!/mySubFolder/myCFunctionsForUnix.so"
var filePath_myLib = localFilemyLib.path; // "file:///C:/Users/Vayeate/AppData/Roaming/Mozilla/Firefox/Profiles/aecgxse.Unnamed%20Profile%201/extensions/youraddon@jetpack.xpi!/mySubFolder/myCFunctionsForUnix.so"

If your add-on is a bootstrap add-on, then you don't need to use this method to convert a chrome:// path; instead, on startup procedure of the bootstrap add-on obtain the File and/or JAR path from installPath from the aData parameter.

function startup(aData, aReason) {
    var nsIFile_folder = aData.installPath; // if addon is unpacked, this will be the addon folder. if addon is packed, this will be addon xpi
}

This can then be joined with your file name to obtain it's path like this:

function startup(aData, aReason) {
    var jarPath_folder = 'jar:' + OS.Path.toFileURI(aData.installPath.path) + '!/'; // if unpacked is false in install.rdf this will look like: "jar:file:///C:/Users/Vayeate/AppData/Roaming/Mozilla/Firefox/Profiles/aksozfjt.Unnamed%20Profile%2010/extensions/AsyncZip@jetpack!/"
    var filePath_folder = aData.installPath.path; // if unpacked is set to false in install.rdf this will look like: "C:\Users\Vayeate\AppData\Roaming\Mozilla\Firefox\Profiles\aksozfjt.Unnamed Profile 10\extensions\AsyncZip@jetpack"
    var filePath_myLib = OS.Path.join(filePath_folder, 'mySubFolder', 'myCFunctionsForUnix.so');
    var jarPath_myLib = jarPath_folder + 'mySubFolder/myCFunctionsForUnix.so';
}

This can then be opened and the C functions within can be used from js-ctypes.

var myLib = ctypes.open(filePath_myLib);
var add_with_c = lib.declare("add", ctypes.default_abi,
    ctypes.int,    // return type
    ctypes.int,    // a
    ctypes.int     // b
);
var rez = add_with_c(2, 5); // rez is 7
lib.close();

References

Standard OS Libraries

See Standard OS Libraries

Document Tags and Contributors

Tags: 
 Contributors to this page: rolfedh, Sheppy, PushpitaPikuDey, Noitidart, arai
 Last updated by: rolfedh,