2

dllファイルをロードstartup()してグローバル変数に保持する小さなブートストラップ拡張機能があります。これを適切に使用する方法が正確にはわかりませんが、これについて修正してくれるかもしれませんが、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 がフリーズしないように呼び出しますか?

4

2 に答える 2

3

外部 ( 経由でバインドされたctypes) API 自体が非同期でない場合、定義上、JavaScript で非同期に呼び出すことはできません。

最も簡単な回避策は、ある種の WebWorker を使用してバックグラウンド スレッドで API を呼び出すことです。いくつかの特権的なことを行う必要があることを考えると、ChromeWorker API は法案に適合します。

そのメカニズムは次のとおりです。

  1. ChromeWorker(別名「ワーカー」)を起動します
  2. 「ワーカー」にメッセージを送信postMessageして、「ジョブ」を開始します
  3. 「ワーカー」のメッセージ イベント ハンドラーが読み込まctypesれ、外部コードへの同期呼び出しが行われます。その後...
  4. 「ワーカー」にメッセージをpostMessage発信者 (メイン コード) に送信してもらいます (事実上、「完了しました」)。

外部 API が呼び出し固有の引数を必要とする場合、最初のpostMessage. 外部 API が重要なものを返す場合、2 番目の を介してそれらを受け取るように編成できますpostMessage

これらはすべてややこしく見えるので、 JavaScript コード モジュールにパッケージ化する必要があります。ctypesこれにより、コードの残りの部分からものを分離することができ、(モジュール内の) 呼び出しスレッドでcreateEventandを使用dispatchEventして、API を非同期に見せながら「ワーカー」部分を非表示にすることができます。

于 2014-06-02T01:12:43.160 に答える
0

これは、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*/
    }
});

私が便利だと思ったスタックオーバーフローに関するその他のjsctype トピック:

于 2014-05-05T06:28:11.647 に答える