上次分享過Windows上的node.js擴展實現。今天分享下如何在Linux平臺上,經過封裝Dynamsoft Barcode SDK for Linux (dbr)來建立node.js barcode addon。javascript
參考原文:How to Make Node Barcode Reader Addon on Linuxhtml
做者:Xiao Lingjava
翻譯:yushulxnode
在Ubuntu上通常習慣用apt-get來安裝軟件。若是是這樣操做,下載的node和npm版本都會比較舊。編譯V8 C/C++代碼的時候會出現錯誤‘FunctionCallbackInfo’ does not name a type:linux
從官網下載最新版本的Linux Node:node-v5.3.0-linux-x64.tar.gz.git
解壓:github
tar -xzf node-v5.3.0-linux-x64.tar.gz
打開.bashrc:
shell
nano ~/.bashrc
導出node的路徑並保存文件:npm
export PATH=$(YOUR_HOME)/Downloads/node-v5.3.0-linux-x64/bin:$PATH
安裝node-gyp:
bash
npm install -g node-gyp
解壓:
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