Revision 59033 of Using js-ctypes

  • Revision slug: Mozilla/js-ctypes/Using_js-ctypes
  • Revision title: Using js-ctypes
  • Revision id: 59033
  • Created:
  • Creator: Sheppy
  • Is current revision? No
  • Comment fix Gecko version; 1 words added, 1 words removed

Revision Content

{{ gecko_minversion_header("2.0") }}

{{ draft() }}

This page will be getting reformatted as work continues; please ignore the untidiness.

Example: Calling Windows routines

This example demonstrates how to use ctypes to call a Win32 API.

Components.utils.import("resource://gre/modules/ctypes.jsm");

var lib = ctypes.open("C:\\WINDOWS\\system32\\user32.dll");

/* Declare the signature of the function we are going to call */
var msgBox = lib.declare("MessageBoxW",
                         ctypes.stdcall_abi,
                         ctypes.int32_t,
                         ctypes.int32_t,
                         ctypes.jschar.ptr,
                         ctypes.jschar.ptr,
                         ctypes.int32_t);
var MB_OK = 3;

var ret = msgBox(0, "Hello world", "title", MB_OK);

lib.close();

In line 3, the user32.dll system library is loaded. Line 6 declares msgBox() to be a method that calls the Windows function MessageBoxW. Line 15 calls the msgBox() routine, which displays the alert.

The last thing we do is call lib.close() to close the library when we're done using it.

Instead of defining the whole path, you may also just give the file name.

var lib = ctypes.open("user32.dll");

Or even without the extension.

var lib = ctypes.open("user32");

If the full path is not given, Windows uses the following search order to locate the DLL:

  1. The directory from which the application loaded.
  2. The system directory.
  3. The 16-bit system directory.
  4. The Windows directory.
  5. The current directory.
  6. The directories that are listed in the PATH environment variable.

(taken from http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx)

Example: Calling Carbon routines on Mac OS X

This example demonstrates how to use ctypes to call a Carbon function on Mac OS X.

/* build a Str255 ("Pascal style") string from the passed-in string */

function makeStr(str) {
  return String.fromCharCode(str.length) + str;
}

Components.utils.import("resource://gre/modules/ctypes.jsm");

var carbon = ctypes.open("/System/Library/Frameworks/Carbon.framework/Carbon");

stdAlert = carbon.declare("StandardAlert",       /* function name */
               ctypes.default_abi,    /* ABI type */
               ctypes.int16_t,        /* return type */
               ctypes.int16_t,        /* alert type */
               ctypes.char.ptr,         /* primary text */
               ctypes.char.ptr,         /* secondary text */
               ctypes.uint32_t,       /* alert param */
               ctypes.int16_t);       /* item hit */

var hit = 0;
var msgErr = makeStr("Carbon Says...");
var msgExp = makeStr("We just called the StandardAlert Carbon function from JavaScript!");

var err = stdAlert(1, msgErr, msgExp, 0, hit);

carbon.close();

The makeStr() function is a utility routine that takes as input a standard JavaScript string and returns a Carbon-style "Pascal" string, which is a length byte followed by the characters of the string itself. Note that this only works correctly if the string is in fact under 256 characters; if it's longer, this will fail spectacularly.

In line 9, the Carbon library is loaded from the system's Carbon framework.

Line 11 declares the stdAlert() function, which will call the Carbon StandardAlert routine. It uses the default ABI, returns a 16-bit integer (which is a Carbon OSErr value), and accepts an integer (the alert type), two strings, a pointer to a parameter block, which we aren't using, and another integer, which is used to return the hit item. See Apple's documentation for StandardAlert for details.

After that, we simply set up our parameters by using makeStr() to generate the two Str255 strings we need, then call stdAlert(), which produces the following alert window:

ctype-mac-dialog.png

The last thing we do is call carbon.close() to close the library when we're done using it.

Example: Calling LibC routines on Linux

This example demonstrates how to use ctypes to call a libc function on Linux.

/* import js-ctypes */
Components.utils.import("resource://gre/modules/ctypes.jsm");

/* open a library */
var libc = ctypes.open("libc.so.6"); 

/* import a function */
var puts = libc.declare("puts", /* function name */
                           ctypes.default_abi, /* call ABI */
                           ctypes.int32_t, /* return type */
                           ctypes.char.ptr /* argument type */
);
var ret = puts("Hello World from js-ctypes!");

Revision Source

<p>{{ gecko_minversion_header("2.0") }}</p>
<p>{{ draft() }}</p>
<p>This page will be getting reformatted as work continues; please ignore the untidiness.</p>
<ul> <li><a href="/en/js-ctypes/Using_js-ctypes/Loading_a_library" title="en/js-ctypes/Using js-ctypes/Loading a library">Loading a library</a></li> <li><a href="/en/js-ctypes/Using_js-ctypes/Declaring_types" title="en/js-ctypes/Using js-ctypes/Declaring types">Declaring types</a></li> <li><a href="/en/js-ctypes/Using_js-ctypes/Working_with_data" title="en/js-ctypes/Using js-ctypes/Working with data">Working with data</a></li>
</ul>
<h2>Example: Calling Windows routines</h2>
<p>This example demonstrates how to use ctypes to call a Win32 API.</p>
<pre class="deki-transform">Components.utils.import("resource://gre/modules/ctypes.jsm");

var lib = ctypes.open("C:\\WINDOWS\\system32\\user32.dll");

/* Declare the signature of the function we are going to call */
var msgBox = lib.declare("MessageBoxW",
                         ctypes.stdcall_abi,
                         ctypes.int32_t,
                         ctypes.int32_t,
                         ctypes.jschar.ptr,
                         ctypes.jschar.ptr,
                         ctypes.int32_t);
var MB_OK = 3;

var ret = msgBox(0, "Hello world", "title", MB_OK);

lib.close();</pre>
<p>In line 3, the <code>user32.dll</code> system library is loaded. Line 6 declares <code>msgBox()</code> to be a method that calls the Windows function <a class=" external" href="http://msdn.microsoft.com/en-us/library/ms645505%28VS.85%29.aspx" title="http://msdn.microsoft.com/en-us/library/ms645505(VS.85).aspx"><code>MessageBoxW</code></a>. Line 15 calls the <code>msgBox()</code> routine, which displays the alert.</p>
<p>The last thing we do is call <code>lib.close()</code> to close the library when we're done using it.</p>
<p>Instead of defining the whole path, you may also just give the file name.</p>
<pre>var lib = ctypes.open("user32.dll");
</pre>
<p>Or even without the extension.</p>
<pre>var lib = ctypes.open("user32");
</pre>
<p>If the full path is not given, Windows uses the following search order to locate the DLL:</p>
<ol> <li>The directory from which the application loaded.</li> <li>The system directory.</li> <li>The 16-bit system directory.</li> <li>The Windows directory.</li> <li>The current directory.</li> <li>The directories that are listed in the PATH environment variable.</li>
</ol>
<p>(taken from <a class=" external" href="http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx" title="http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx">http://msdn.microsoft.com/en-us/library/ms682586(VS.85).aspx</a>)</p>
<h2>Example: Calling Carbon routines on Mac OS X</h2>
<p>This example demonstrates how to use ctypes to call a Carbon function on Mac OS X.</p>
<pre class="deki-transform">/* build a Str255 ("Pascal style") string from the passed-in string */

function makeStr(str) {
  return String.fromCharCode(str.length) + str;
}

Components.utils.import("resource://gre/modules/ctypes.jsm");

var carbon = ctypes.open("/System/Library/Frameworks/Carbon.framework/Carbon");

stdAlert = carbon.declare("StandardAlert",       /* function name */
               ctypes.default_abi,    /* ABI type */
               ctypes.int16_t,        /* return type */
               ctypes.int16_t,        /* alert type */
               ctypes.char.ptr,         /* primary text */
               ctypes.char.ptr,         /* secondary text */
               ctypes.uint32_t,       /* alert param */
               ctypes.int16_t);       /* item hit */

var hit = 0;
var msgErr = makeStr("Carbon Says...");
var msgExp = makeStr("We just called the StandardAlert Carbon function from JavaScript!");

var err = stdAlert(1, msgErr, msgExp, 0, hit);

carbon.close();
</pre>
<p>The <code>makeStr()</code> function is a utility routine that takes as input a standard JavaScript string and returns a Carbon-style "Pascal" string, which is a length byte followed by the characters of the string itself. Note that this only works correctly if the string is in fact under 256 characters; if it's longer, this will fail spectacularly.</p>
<p>In line 9, the Carbon library is loaded from the system's Carbon framework.</p>
<p>Line 11 declares the <code>stdAlert()</code> function, which will call the Carbon <code>StandardAlert</code> routine. It uses the default ABI, returns a 16-bit integer (which is a Carbon <code>OSErr</code> value), and accepts an integer (the alert type), two strings, a pointer to a parameter block, which we aren't using, and another integer, which is used to return the hit item. See Apple's documentation for <a class=" external" href="http://developer.apple.com/legacy/mac/library/documentation/Carbon/Reference/Dialog_Manager/Reference/reference.html#//apple_ref/c/func/StandardAlert" title="http://developer.apple.com/legacy/mac/library/documentation/Carbon/Reference/Dialog_Manager/Reference/reference.html#//apple_ref/c/func/StandardAlert"><code>StandardAlert</code></a> for details.</p>
<p>After that, we simply set up our parameters by using <code>makeStr()</code> to generate the two <code>Str255</code> strings we need, then call <code>stdAlert()</code>, which produces the following alert window:</p>
<p><img alt="ctype-mac-dialog.png" class="internal default" src="/@api/deki/files/4559/=ctype-mac-dialog.png"></p>
<p>The last thing we do is call <code>carbon.close()</code> to close the library when we're done using it.</p>
<h2>Example: Calling LibC routines on Linux</h2>
<p>This example demonstrates how to use ctypes to call a libc function on Linux.</p>
<pre class="deki-transform">/* import js-ctypes */
Components.utils.import("resource://gre/modules/ctypes.jsm");

/* open a library */
var libc = ctypes.open("libc.so.6"); 

/* import a function */
var puts = libc.declare("puts", /* function name */
                           ctypes.default_abi, /* call ABI */
                           ctypes.int32_t, /* return type */
                           ctypes.char.ptr /* argument type */
);
var ret = puts("Hello World from js-ctypes!");
</pre>
Revert to this revision