したがって、この難しさの答えはjs-ctypesライブラリになります。JavaScriptがローカルコード(Cで記述された)を呼び出し、XPCOMを使用せずにデータ型を操作できるようにします。1行のコードをコンパイルする必要はありません。 これは、XPCOMインターフェースを定義する必要がなく、libcのような共有ライブラリを直接使用できることを意味します。 副次的なプラスの効果があります。ほとんどの場合、XPConnectに固有のデータ型変換が排除されるため、コードの実行が高速になります。 (次のブログエントリの1つで速度の比較を行います。)js-ctypesライブラリはGecko 1.9.3に同梱され、このプラットフォーム(バージョン番号が変更されない場合)がFirefox 3.7の基盤になります。
あなたは尋ねるかもしれません:「しかし、どのように...?」 そして、いくつかの例があります(x86 32ビットLinuxでテストされ、
1)ライブラリを開きます。
// ctypes.
Components.utils.import( "resource://gre/modules/ctypes.jsm" );
// libc.
let library = ctypes.open( "libc.so.6" );
// fopen, -:
// FILE* fopen(const char* name, const char* mode);
let fopen = library.declare( "fopen" , //
ctypes.default_abi, // cdecl
ctypes.PointerType( "FILE*" ), // (FILE*)
ctypes. char .ptr, // (const char*)
ctypes. char .ptr); // (const char*)
// , FILE*.
let file = fopen( "hello world.txt" , "w" );
// 'file'?
file.toString();
// "ctypes.PointerType("FILE*")(ctypes.UInt64("0x9781b38"))" ( )
// ... ...
* This source code was highlighted with Source Code Highlighter .
2)構造タイプ(構造)と配列の定義と使用。
// struct 'hostent', ,
// .
// :
// struct hostent {
// char* h_name; //
// char** h_aliases; // ,
// int h_addrtype; // IPv4 IPv6
// int h_length; // ( ) IP-
// char** h_addr_list; // IP- ( )
// };
let hostent = ctypes.StructType( "hostent" ,
[{ h_name : ctypes. char .ptr },
{ h_aliases : ctypes. char .ptr.ptr },
{ h_addrtype : ctypes. int },
{ h_length : ctypes. int },
{ h_addr_list : ctypes.uint8_t.array(4).ptr.ptr }]);
// 'gethostbyname', -:
// struct hostent* gethostbyname(const char* name);
let gethostbyname = library.declare( "gethostbyname" ,
ctypes.default_abi,
hostent.ptr, // 'hostent'
ctypes. char .ptr);
// .
let google = gethostbyname( "mail.google.com" );
// struct 'hostent',
// 'h_name',
// . :
// printf("%s", google->h_name);
google.contents.h_name.readString();
// "googlemail.l.google.com"
// 'h_addr_list',
// ,
// IPv4- .
// -:
// printf("%u.%u.%u.%u", (int) h_addr_list[0][0], (int) h_addr_list[0][1],
// (int) h_addr_list[0][2], (int) h_addr_list[0][3]);
google.contents.h_addr_list.contents.contents.toString();
// "ctypes.uint8_t.array(4)([74, 125, 19, 17])" , 74.125.19.17
* This source code was highlighted with Source Code Highlighter .
3)JavaScript関数を指すCのような関数ポインターを作成します。
(ライブラリのこの部分はまだ準備ができていませんが、パッチの作業が進行中であることに注意してください。)
// ,
// , :
// -1, i < j;
// 0, i == j;
// 1, i > j.
// - :
// typedef int (comparator_t*)(const int8_t* i, const int8_t* j);
let comparator_t = ctypes.FunctionType(ctypes.default_abi, ctypes. int ,
ctypes.int8_t.ptr, ctypes.int8_t.ptr);
// - 'comparator_t'?
comparator_t.name;
// "int (*)(int8_t*,int8_t*)"
// 'qsort', ,
// , .
// void qsort(void* array, size_t length, size_t elemsize, comparator_t comp);
let qsort = library.declare( "qsort" , ctypes.default_abi, ctypes.void_t,
ctypes.voidptr_t, ctypes.size_t, ctypes.size_t, comparator_t);
// , 'comparator_t'.
function reverse(i, j) { return j.contents - i.contents; }
// , .
let reverse_ptr = comparator_t(reverse);
// 'reverse_ptr'?
reverse_ptr.toString();
// "ctypes.FunctionType(ctypes.default_abi, ctypes.int, ctypes.int8_t.ptr,
// ctypes.int8_t.ptr)(ctypes.UInt64("0x81a430cb"))"
// 'qsort'.
let array_t = ctypes.int8_t.array();
let ints = array_t([3, 1, 5, 6, 4, 2]);
qsort(ints.address(), ints.length, array_t.elementType.size, reverse_ptr);
// !
ints.toString();
// "ctypes.int8_t.array(6)([6, 5, 4, 3, 2, 1])"
* This source code was highlighted with Source Code Highlighter .
そのため、拡張機能の作成者、