前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SWIG与nodejs入门

SWIG与nodejs入门

作者头像
音视频_李超
发布2020-04-01 20:22:28
1.9K0
发布2020-04-01 20:22:28
举报

前言

Javascipt是一种基于原型的脚本语言。它是动态的,弱类型的语言。它可以说是最流行的Web开发语言。Javascript已经超越了基于浏览器的脚本语言,并且与node.js一起,它也被用作后端开发语言。

SWIG Javascript目前支持JavascriptCore,Safari / Webkit使用的Javascript引擎,以及Chromium和node.js使用的v8。

运行 SWIG

假设您像下面这样,定义了一个SWIG模块:

代码语言:javascript
复制
%module example
%{
#include "example.h"
%}
int gcd(int x, int y);
extern double Foo;

要构建Javascript模块,请使用 -javascript 选项和所希望的目标引擎如:-jsc-v8-node 运行SWIG。node生成器基本上委托给v8生成器并添加一些必要的预处理器定义。

代码语言:javascript
复制
$ swig -javascript -jsc example.i

如果构建C ++扩展,请添加-c ++选项:

代码语言:javascript
复制
$ swig -c++ -javascript -jsc example.i

SWIG生成的V8代码应适用于从3.11.10到3.29.14及更高版本的大多数版本。 大于等于 4.3.0的 V8 API头定义了SWIG用于决定其正在编译的V8版本的常量。小于 4.3的版本,在运行 SWIG时,你要指定V8的版本。版本号是一个16进制的常量,但是常量被读作十进制数字对。如 V8 3.25.30使用常量 0x032530。这种模式不能表达超过 99的数字,但此常量仅在V8版本小于 4.3.0时才使用。并且目前没有任何 V8版本超过了 99。例如:

代码语言:javascript
复制
$ swig -c++ -javascript -v8 -DV8_VERSION=0x032530 example.i

如果你的目标 V8 版本直超过 4.3.0,你应该像下面这样运行 swig:

代码语言:javascript
复制
$ swig -c++ -javascript -v8 example.i

它将创建一个 名为 example_wrap.c 或 example_wrap.cxx 的 C/C++ 文件。产生的 C 源文件包括许多需要被编译底层wapper并与剩下的C/C++应用链接到一起生成一个扩展模块。

wraper文件的名子来自于输入文件。例如, 如果输入文件是 example.i,那么wraper文件的名子就是example_wrap.c。如果要改变它,你可以使用 -o 选项。wrapper模块将导出一个必须被调用的函数,以便将它注册到 javascript解释器中。例如,如果你的模块命名为 example,那么对于 JavascriptCore 对应的初始化函数应该如下:

代码语言:javascript
复制
bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports)

对于 V8

代码语言:javascript
复制
void example_initialize(v8::Handle<v8::Object> exports)

注意: V8使用C ++ API,因此,生成的模块必须编译为C ++

运行测试和例子

对于测试和例子的配置当前仅支持 Linux和Mac,而不支持 MinGW(Windows)。

默认解释器是node.js,因为它在所有平台上都可用并且使用方便。

使用JavascriptCore运行示例需要安装libjavascriptcoregtk-1.0,例如,在Ubuntu下安装

代码语言:javascript
复制
$ sudo apt-get install libjavascriptcoregtk-1.0-dev

使用V8运行需要libv8:

代码语言:javascript
复制
$ sudo apt-get install libv8-dev

可以使用示例运行

代码语言:javascript
复制
$ make check-javascript-examples ENGINE=jsc

ENGINE可以是node,jsc或v8。

测试套件可以使用

代码语言:javascript
复制
$ make check-javascript-test-suite ENGINE=jsc

您可以指定用于运行示例和测试的特定V8版本

代码语言:javascript
复制
$ make check-javascript-examples V8_VERSION=0x032530 ENGINE=v8

创建 node.js 扩展

对于Mac和Windows用户可以下载安装包安装node.js。对于Linux用户,你即可以通过 build 源码安装它,也可以通过包安装。

由于v8是用C ++编写的,并且作为C ++库,因此使用与构建v8相同的编译器标志来编译模块至关重要。为了简化操作,node.js提供了一个名为node-gyp的构建工具。

你必须使用npm安装它:

代码语言:javascript
复制
sudo npm install -g node-gyp

node-gyp需要一个名为binding.gyp的配置文件,该文件基本上是JSON格式,并且符合与Google的构建工具gyp一样的格式

binding.gyp:

代码语言:javascript
复制
{
  "targets": [
    {
      "target_name": "example",
      "sources": [ "example.cxx", "example_wrap.cxx" ]
    }
  ]
}

首先使用SWIG创建包装器:

代码语言:javascript
复制
$ swig -javascript -node -c++ example.i

然后运行node-gyp build来实际创建模块:

代码语言:javascript
复制
$ node-gyp build

这将创建一个包含Native模块的build文件夹。要使用扩展程序,您需要在Javascript源文件中“require”它:

代码语言:javascript
复制
require("./build/Release/example")

例子部分中给出了更详细的解释。

问题

  • 'module' 对免没有'script_main'属性 当gyp作为分发包安装时会发生此错误。它似乎已经过时了。删除它可以解决问题。
代码语言:javascript
复制
sudo apt-get remove gyp

例子

这里展示一些基本例子和更多的细节:

代码语言:javascript
复制
/* File : example.i */
%module example

%inline %{
extern int    gcd(int x, int y);
extern double Foo;
%}

要使其node扩展,必须创建binding.gyp:

代码语言:javascript
复制
{
  "targets": [
    {
      "target_name": "example",
      "sources": [ "example.cxx", "example_wrap.cxx" ]
    }
  ]
}

然后node-gyp用于构建扩展:

代码语言:javascript
复制
$ node-gyp configure build

从'nodejs`应用程序将像这样使用扩展:

代码语言:javascript
复制
// import the extension via require
var example = require("./build/Release/example");

// calling the global method
var x = 42;
var y = 105;
var g = example.gcd(x, y);

// Accessing the global variable
var f = example.Foo;
example.Foo = 3.1415926;

首先,加载先前build的扩展example 模块。模块中的全局方法和变量是有效的。

常见的示例类定义了三个类:Shape,Circle和Square:

代码语言:javascript
复制
class Shape {
public:
  Shape() {
    nshapes++;
  }
  virtual ~Shape() {
    nshapes--;
  }
  double  x, y;
  void    move(double dx, double dy);
  virtual double area(void) = 0;
  virtual double perimeter(void) = 0;
  static  int nshapes;
};

class Circle : public Shape {
private:
  double radius;
public:
  Circle(double r) : radius(r) { }
  virtual double area(void);
  virtual double perimeter(void);
};

class Square : public Shape {
private:
  double width;
public:
  Square(double w) : width(w) { }
  virtual double area(void);
  virtual double perimeter(void);
};

Circle和Square继承自Shape。Shape具有静态变量nshapes, move函数不能被重载(非虚函数),并且有两个抽象函数areaperimeter(纯虚函数)必须由子类重载。

nodejs扩展的build方式与simple示例相同。

在Javascript中,它可以使用如下:

代码语言:javascript
复制
var example = require("./build/Release/example");

// local aliases for convenience
var Shape = example.Shape;
var Circle = example.Circle;
var Square = example.Square;

// creating new instances using the 'new' operator
var c = new Circle(10);
var s = new Square(10);

// accessing a static member
Shape.nshapes;

// accessing member variables
c.x = 20;
c.y = 30;
s.x = -10;
s.y = 5;

// calling some methods
c.area();
c.perimeter();
s.area();
s.perimeter();

// instantiation of Shape is not permitted
new Shape();

小结

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 运行 SWIG
  • 运行测试和例子
  • 创建 node.js 扩展
  • 问题
  • 例子
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档