Create a simple js-ctypes example

时间:2021-12-22 19:01:35

js-ctypes 为Firefox extension访问由C/C++编写的native code提供了一种通用的方法。

从Firefox 4 开始支持js-ctypes,不同版本的之间有极好的兼容性。即使Firefox不断升级,也不需要修改native code,因此js-ctypes大受FF extension 开发者的青睐。

本文将会用一个简单的例子说明在Windows平台如何load dll 文件以及调用简单API。

Native Code:

这部分定义了一个求和的API, 将传入的两位参数相加,并返回结果。我们通过.def文件来export API,如下:

AddTest.cpp, to define logic of AddTest method.

int WINAPI AddTest(int a, int b)
{
return a + b;
}

AddTest.def, to export AddTest method.

LIBRARY "ctypes_simpleEx"

    EXPORTS
AddTest

  

JS Code:

这部分的目的是通过运行extension,获取2+5的和。包括三部分:

1. 获取dll的绝对路径

2. 加载dll

3. 声明函数

4. 调用函数,求和

Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/ctypes.jsm"); var cr = Components.classes['@mozilla.org/chrome/chrome-registry;1'].getService(Components.interfaces.nsIChromeRegistry); // get path of lib
var chromeURI_myLib = Services.io.newURI("chrome://burningfish/content/resources/ctypes_simpleEx.dll", null, null);
var localFile_myLib = cr.convertChromeURL(chromeURI_myLib);
var jarPath_myLib = localFile_myLib.spec;
var filePath_myLib = localFile_myLib.path;
if(OATS.OpenScript.Util.StringUtil.startWith(filePath_myLib,"/")){
filePath_myLib=filePath_myLib.substring(1);
} //load files
var myLib;
try{
myLib = ctypes.open(filePath_myLib);
}catch(ex){
console.log("Load natice file error:" + ex);
} // declare the AddTest method
this.add = myLib.declare("AddTest", ctypes.winapi_abi,
ctypes.int, // return type
ctypes.int, // a
ctypes.int // b
); // call AddTest, and get result of 2+5
var rez = this.add(2, 5); // rez is 7
alert("2+5 result is " + rez);

JS Code需要注意的两个地方:

1. ABI

Mozilla提供三种ABI(Application Binary Interface), ctypes.default_abi, ctypes.stdcall_abi, ctypes.winapi_abi.

三种ABI都适用Windows平台,具体用哪个ABI视native code 方法的定义方式而定。本例子native部分定义的是WINAPI方法,声明函数的时候需要用ctypes.winapi_abi。

如果是stdcall定义的函数,需要用ctypes.stdcall_abi。这两种之外的定义方式都用ctypes.default_abi。

2. 类型

Mozilla官方文档有对ctypes非常详细的描述,https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/js-ctypes_reference/ctypes。

声明函数的时候需要将native code的类型与ctypes类型严格对应起来。

例子中使用的参数类型和返回类型都是int, 使用ctypes.int 对应。

ctypes还提供了ctypes.int32_t, ctypes.int64_t, 在32位application 里面可以使用ctypes.int32_t, 64位application里面使用ctypes.int64_t。

上述描述了js-cypes简单调用dll method的例子,后续还会将指针、回调函数使用等的方法跟大家分享。

笔者是js-ctypes初学者,以上是学习中的一点经验和收获,分享给大家,若有不对之处,还请不惜赐教。