如何在Ubuntu上创建Node.js Addon
jopen
9年前
上次分享过Windows上的node.js扩展实现。今天分享下如何在Linux平台上,通过封装Dynamsoft Barcode SDK for Linux (dbr)来创建node.js barcode addon。
参考原文:How to Make Node Barcode Reader Addon on Linux
作者:Xiao Ling
翻译:yushulx
软件下载
在Ubuntu上一般习惯用apt-get来安装软件。如果是这样操作,下载的node和npm版本都会比较旧。编译V8 C/C++代码的时候会出现错误‘FunctionCallbackInfo’ does not name a type:
安装Node
从官网下载最新版本的Linux Node:node-v5.3.0-linux-x64.tar.gz.
解压:
tar -xzf node-v5.3.0-linux-x64.tar.gz
打开.bashrc:
nano ~/.bashrc
导出node的路径并保存文件:
export PATH=$(YOUR_HOME)/Downloads/node-v5.3.0-linux-x64/bin:$PATH
安装node-gyp:
npm install -g node-gyp
安装DBR
解压:
tar -xzf v4.0.0-pre-alpha.tar.gz
为了方便编译的时候找到SDK中提供的*.so动态链接库,创建一个符号链接:
sudo ln -s $(DynamsoftBarcodeReader)/Redist/libDynamsoftBarcodeReaderx64.so /usr/lib/libDynamsoftBarcodeReaderx64.so
创建Node Barcode Addon
创建文件 binding.gyp,在里面添加目标名,源码路径,include路径,以及依赖库的路径。
{ "targets": [ { "target_name": "dbr", "sources": [ "dbr.cc" ], "include_dirs" : [ "$(DynamsoftBarcodeReader)/Include" ], "libraries": [ "-lDynamsoftBarcodeReaderx64", "-L$(DynamsoftBarcodeReader)/Redist" ] } ] }
参考SDK中提供的sample,创建dbr.cc:
#include <node.h> #include "If_DBR.h" #include "BarcodeFormat.h" #include "BarcodeStructs.h" #include "ErrorCode.h" using namespace v8; // Barcode format const char * GetFormatStr(__int64 format) { if (format == CODE_39) return "CODE_39"; if (format == CODE_128) return "CODE_128"; if (format == CODE_93) return "CODE_93"; if (format == CODABAR) return "CODABAR"; if (format == ITF) return "ITF"; if (format == UPC_A) return "UPC_A"; if (format == UPC_E) return "UPC_E"; if (format == EAN_13) return "EAN_13"; if (format == EAN_8) return "EAN_8"; if (format == INDUSTRIAL_25) return "INDUSTRIAL_25"; if (format == QR_CODE) return "QR_CODE"; if (format == PDF417) return "PDF417"; if (format == DATAMATRIX) return "DATAMATRIX"; return "UNKNOWN"; } void DecodeFile(const FunctionCallbackInfo<Value>& args) { Isolate* isolate = Isolate::GetCurrent(); HandleScope scope(isolate); // convert v8 string to char * String::Utf8Value fileName(args[0]->ToString()); String::Utf8Value license(args[1]->ToString()); char *pFileName = *fileName; char *pszLicense = *license; // Dynamsoft Barcode Reader: init __int64 llFormat = (OneD | QR_CODE | PDF417 | DATAMATRIX); int iMaxCount = 0x7FFFFFFF; ReaderOptions ro = {0}; pBarcodeResultArray pResults = NULL; // Initialize license if (pszLicense) { printf("license: %s\n", pszLicense); DBR_InitLicense(pszLicense); } else DBR_InitLicense("AC4561856D63EF392F46D7454052372D"); ro.llBarcodeFormat = llFormat; ro.iMaxBarcodesNumPerPage = iMaxCount; // Decode barcode image int ret = DBR_DecodeFile(pFileName, &ro, &pResults); printf("ret: %d\n", ret); if (ret == DBR_OK){ int count = pResults->iBarcodeCount; pBarcodeResult* ppBarcodes = pResults->ppBarcodes; pBarcodeResult tmp = NULL; // javascript callback function Local<Function> cb = Local<Function>::Cast(args[2]); const unsigned argc = 1; // array for storing barcode results Local<Array> barcodeResults = Array::New(isolate); for (int i = 0; i < count; i++) { tmp = ppBarcodes[i]; Local<Object> result = Object::New(isolate); result->Set(String::NewFromUtf8(isolate, "format"), Number::New(isolate, tmp->llFormat)); result->Set(String::NewFromUtf8(isolate, "value"), String::NewFromUtf8(isolate, tmp->pBarcodeData)); barcodeResults->Set(Number::New(isolate, i), result); } // release memory DBR_FreeBarcodeResults(&pResults); Local<Value> argv[argc] = { barcodeResults }; cb->Call(isolate->GetCurrentContext()->Global(), argc, argv); } } void Init(Handle<Object> exports) { NODE_SET_METHOD(exports, "decodeFile", DecodeFile); } NODE_MODULE(dbr, Init)
通过命令自动创建工程构建的文件:
node-gyp configure
创建之后makefile不需要再进行手动修改了。现在可以构建工程了:
node-gyp build
写一个测试dbr.js,包含读取license以及调用C/C++接口:
var dbr = require('./build/Release/dbr'); var readline = require('readline'); var fs = require('fs'); fs.readFile('./license.txt', 'utf8', function (err, data) { if (err) throw err; var rl = readline.createInterface({ input: process.stdin, output: process.stdout }); var license = data.trim(); rl.question("Please input a barcode image path: ", function(answer) { dbr.decodeFile( answer, license, function(msg){ var result = null; for (index in msg) { result = msg[index] console.log(result['format']); console.log(result['value']); console.log("##################"); } } ); rl.close(); }); });
运行脚本:
node dbr.js
源码
https://github.com/dynamsoftsamples/node-barcode-addon-for-linux