LoginSignup
7
7

More than 5 years have passed since last update.

nw.js@0.8.6からnode-ffiでネイティブモジュールを叩く

Last updated at Posted at 2015-03-22

まず、nodeからネイティブモジュールを叩くには、node-ffiを使用します。

node-ffiですが、nodeのバージョンが0.10から0.12になるにかけて、ネイティブモジュールに関係する部分で後方互換性が失われてしまうという事件が起こっています。

現状0.11や0.12で動かすことは不可能ではないですが、私は落ち着いてから試すことにしました。

詳しい内容は、"NAN node"とかでググるか以下の記事をみるといいかもしれません。

今回は、このへんの話には、触れないでv0.10系を使うことにします。

環境

  • Ubuntu 14.10 (x64)

OSXでも同じようにできる気がします。

nw.jsのインストール

npmで古いnwをインストールできなかったので、tarを落とします。

nwjs/nw.js

OSに合わせてnw@0.8.6をダウンロードします。

ネイティブモジュールの後方互換性のために、nodeのv0.10系を使用している、v0.8系もメンテされているようです。

nw@0.8.6は、node@0.10.22/Chrome@30.0.1599.66です。

配置

まず、nvmで0.10.22をインストールします。(v.10でもいいかもしれません)

$ nvm install v0.10.22

サンプルを作成するために、お好みでディレクトリを掘って、package.jsonを作成します(npm init)

$ mkdir path/to/dir
$ cd path/to/dir
$ npm init
(index.jsの部分を、index.htmlにする、ほかはEnter)

node-ffiもインストールしておきます。

$ npm install -save ffi

さっきダウンロードしたnwを解凍して、node_modulesに配置しておきます(nwコマンドを叩くだけなので、別にどこでもいいです。)

$ mv path/to/node-webkit-v0.8.6-linux-x64 ./node_modules

Linux系OSの場合のエラー

nwを実行すると、多分次のエラーが出ます。

error while loading shared libraries: libudev.so.0: cannot open shared object file: No such file or directory

それについては、ドキュメントでも言及されているので参考にします。

The solution of lacking libudev.so.0 · nwjs/nw.js Wiki

バイナリを書き換えてしまうのが手軽そうなのでそうします(他の方法もあります)

$ cd node_modules/node-webkit-v0.8.6-linux-x64
$ sed -i 's/udev\.so\.0/udev.so.1/g' nw

node-ffiのビルド

nw@0.8.6向けにnode-ffiをリビルドします。

nodeのネイティブアドオンのビルドには、node-gypを使いますが、nw向けに便利化されたnw-gypがあるのでそちらを使います。

nw-gypをグローバルにインストールします。

$ npm install -g nw-gyp

nw-gypを使ってnode-ffiをリビルドします。targetには今回使用するnw.jsのバージョン(0.8.6)を指定します。

$ cd node_modules/ffi
$ nw-gyp rebuild --target=0.8.6

ffiの依存関係で入っている"ref"もリビルドします。

$ cd node_modules/ffi/node_modules/ref
$ nw-gyp rebuild --target=0.8.6

さらに、依存関係で入っている"ref-struct"の依存関係で入っている"ref"もリビルドします。

$ cd node_modules/ffi/node_modules/ref-struct/node_modules/ref
$ nw-gyp rebuild --target=0.8.6

これら全部をビルドしないと、以下のようなエラーが出るはずです。

...(略)...
undefined symbol: _ZN2v86String3NewEPKci

サンプルを動かしてみる

node-ffiのREADMEでlibmを動かしているの、同じように使えるか試してみます。

index.html
<!DOCTYPE html>
<html>
  <head>
    <title>Hello FFI!</title>
  </head>
  <body>
    <h1>Hello FFI!</h1>
    <script>
    var ffi = require("ffi");
    var math = ffi.Library('libm', {
      'sqrt': [ 'double', [ 'double' ] ]
    });
    var x = math.sqrt(2); // sqrt(2)=1.4142135623730951
    document.write(x.toString());
    </script>
  </body>
</html>

nwを起動すると、√2が表示されるはずです。

$ ./node_modules/node-webkit-v0.8.6-linux-x64/nw .

Screenshot from 2015-03-22 16:01:21.png

おお、ffi使えてます。

まとめ

依存関係のrefまでリビルドしないといけないのに気づくのに少し時間がかかりましたが、nwでもffi動くようです。

調べていると、解決していないパターン(How to use node-ffi in node-webkit? · Issue #138 · node-ffi/node-ffi)が多くて困りました。

以下のサンプルも動かせそうですが、gruntとかを使ってて構成が少し複雑そうだったので試してません。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7