在无重启扩展中与jsctypes异步工作



我有一个小的引导扩展,在startup()加载一个dll文件,并将其保存在一个全局变量中。我不知道如何正确使用这个也许你会纠正我,但我更感兴趣的是知道我从dll文件中使用的函数是否可以异步调用。

现在我正在做的是:

Components.utils.import("resource://gre/modules/ctypes.jsm");
log = function(str) { Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).logStringMessage(str+'n'); }
var lib;
var someFunc;
...
function startup(aData, aReason) {
   lib = ctypes.open(dllPath);
   if(!lib)
   {
      log("dll load error");
      lib = null;
      return;
   }
   else
   {
      var initDll = lib.declare("Init", ctypes.default_abi, ctypes.long);
      var status = initDll();
      log("Dll returned " + status);
      if(status == ctypes.long(0))
      {
         someFunc = lib.declare("SomeFunc", ctypes.default_abi, ctypes.long, ctypes.long);
      }
   }
}

一旦我有了someFunc,我就经常在代码中使用它,但是调用需要很长时间。是否有一种方法可以异步调用它?或者以这样一种方式调用它,Firefox在调用期间不会冻结?

如果外部(通过ctypes绑定)API本身不是异步的,根据定义,您将无法在JavaScript中异步调用它。

最简单的解决方法是使用某种WebWorker在后台线程中调用API。看到你需要做一些特权的东西,ChromeWorker api符合要求。

它的机制是:

  1. 启动ChromeWorker(即'worker')
  2. 通过postMessage向'worker'发送消息以启动'job'
  3. worker中的消息事件处理程序应该加载ctypes并对外部代码进行同步调用,然后…
  4. 让'worker'通过postMessage发送消息给调用者(你的主代码)说(有效地,"我完成了")。

如果外部API需要特定于调用的参数,您可以通过第一个postMessage组织发布这些参数。如果外部API返回任何重要的东西,您可以组织通过第二个postMessage接收这些。

所有这些看起来有点繁琐,所以你需要将其打包到JavaScript代码模块中;这将允许你把ctypes的东西从你的代码的其余部分分开,你可以使用createEventdispatchEvent在调用线程(在模块内),使API看起来是异步的,但隐藏'worker'的部分。

这里展示了如何对jsctypes使用不同的函数。这可能不是特定于你上面的东西,如果这对你没有帮助,让我知道,我会看看你的具体情况。

const {Cc, Ci, Cu} = require('chrome');
Cu.import("resource://gre/modules/ctypes.jsm");
/*start getcursorpos*/
var lib = ctypes.open("user32.dll");
/*foreground window stuff*/
var FindWindowA = lib.declare('FindWindowA', ctypes.winapi_abi, ctypes.uint32_t, ctypes.jschar.ptr, ctypes.jschar.ptr)
var GetForegroundWindow = lib.declare('GetForegroundWindow', ctypes.winapi_abi, ctypes.uint32_t)
function doFindWindow() {
    var wm = Cc['@mozilla.org/appshell/window-mediator;1'].getService(Ci.nsIWindowMediator);
    var title = wm.getMostRecentWindow('navigator:browser').gBrowser.contentDocument.title;
    Cu.reportError('title=' + title)
    var ret = FindWindowA('', title + ' - Mozilla Firefox');
    //var ret = GetForegroundWindow();
    Cu.reportError(ret);
}
/*end foreground window stuff*/
/* Declare the signature of the function we are going to call */
const struct_lpPoint = new ctypes.StructType("lpPoint",
                        [ { "x": ctypes.int },
                          { "y": ctypes.int } ]);
var GetCursorPos = lib.declare('GetCursorPos', ctypes.winapi_abi, ctypes.bool, struct_lpPoint.ptr);
function doGetCursorPos() {
        var point = new struct_lpPoint;
        var ret = GetCursorPos(point.address());
        Cu.reportError(ret);
        Cu.reportError(point);
}
/*end getcursorpos*/


/*start setcursorpos*/
//var lib = ctypes.open("user32.dll"); //already called on line 4
var SetCursorPos = lib.declare('SetCursorPos', ctypes.winapi_abi, ctypes.bool, ctypes.int, ctypes.int)
function doSetCursorPos() {
    var ret = SetCursorPos(10, 10);
}
/*end setcursorpos*/
/*start mouse_event*/
//used to click
//const DWORD = ctypes.uint32_t; //this just shows you that DWORD == ctypes.uint32_t
var mouse_event = lib.declare('mouse_event', ctypes.winapi_abi, ctypes.void_t, ctypes.uint32_t, ctypes.uint32_t, ctypes.uint32_t, ctypes.uint32_t, ctypes.uintptr_t);
const MOUSEEVENTF_LEFTDOWN = 2;
const MOUSEEVENTF_LEFTUP = 4;
function domouse_event() {
    var ret = mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
    var ret = mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
}
/*end mouse_event*/

/*start MessageBoxW*/
//var lib = ctypes.open("user32.dll"); //already called on line 4
var MessageBoxW = lib.declare('MessageBoxW', ctypes.winapi_abi, ctypes.int32_t, ctypes.int32_t, ctypes.jschar.ptr, ctypes.jschar.ptr, ctypes.int32_t);
var MB_OK = 0;
function doMessageBoxW() {
    var ret = MessageBoxW(0, "Hello world", "title", MB_OK);
}
/*end MessageBoxW*/
exports.main = function (options, callbacks) {

};

exports.onUnload = function (reason) {
    lib.close();
}
var { Hotkey } = require("hotkeys");
var showHotKey = Hotkey({
    combo: "alt-w",
    onPress: function() {
        /*setcursor stuff*/
        //doSetCursorPos();
        //domouse_event();
        /*setcursor stuff*/
        /*foreground stuff*/
        doFindWindow();
        /*foreground stuff*/
    }
});

我发现stackoverflow上的其他jsctype主题很有用:* Javascript字符串到c++ char指针-LPSTR缓冲区在JSCTypes如何在javascript中声明C函数fgets

相关内容

  • 没有找到相关文章

最新更新