C++編寫nodejs擴展實戰

C++編寫nodejs擴展實戰

以前有用PHP寫過根據IP地址查詢IP歸屬地,後來改用C語言編寫,效率果真大幅度提升,而後轉化爲PHP的擴展.

想起以前有過使用手機號碼查詢號碼歸屬地,最近又有在研究nodejs,因而就使用C++編寫了nodejs的擴展.

遇到的問題確實很多,記錄下來,供你們參考:

1.字符編碼的問題:nodejs對於gbk編碼支持不夠好,爲了提升程序效率,先把IP歸屬地的資源轉化爲utf-8的編碼,具體使用PHP腳本foreach使用iconv轉換

2.參數傳遞的問題,不少程序裏面都寫個helloworld的nodejs擴展的C++實現,可是這裏面沒有參數傳遞吶,參考了nodejs官網,老是找不到int類型,怎麼從javascript轉化爲C++,本着有困難找度孃的心理,果真讓我找到了:使用args[0]->Int32Value()就能夠轉化了

3.具體編寫的過程以下:

a.編寫binding.gyp,先寫好最簡配置:

{
'targets':[
{
'target_name':'mtc'
'source':['mtc.cc']
}
]
}
其中target_name是模塊名,require的時候用
source是C++源文件的名字放在binding.gyp同目錄下javascript

b.編寫C++的源代碼:

#include <node.h>
#include <v8.h>
using namespace v8;
const int MaxCityLength = 25;

char* Search(const char* fileName, const int& number);
class Info{
public:
Info():m_before(0),m_after(0),m_cityIndex(0) {java

}
Info(int begin, unsigned short skip, unsigned short city_index){
    setBegin(begin);
    setSkip(skip);
    m_cityIndex = city_index;
}
int getBegin() {
    int lastTwo = m_after - getNumberExceptLastTwo()*100;
    return m_before * 100 + lastTwo;
}

unsigned short getNumberExceptLastTwo() {
    return m_after * 0.01;
}

unsigned short getCityIndex() {
    return m_cityIndex;
}

unsigned short getLastTwo(int number) {
    int exceptLastTwoNum = number * 0.01;
    return (number - exceptLastTwoNum * 100);
}

void setBegin(int& number) {
    int lastTwo = getLastTwo(number);
    m_before = number * 0.01;
    m_after = getNumberExceptLastTwo();
}

void setSkip(unsigned short skip) {
    m_after = getNumberExceptLastTwo() * 100 + getLastTwo(m_after);
}

void setCityIndex(unsigned short& city) {
    m_cityIndex = city;
}
char* FindResult(FILE* file, const int& count, Info info){
    int totalOffset = sizeof(int) + count*sizeof(Info) + info.getCityIndex()* MaxCityLength;
    fseek(file, totalOffset,SEEK_SET);
    char* location = new char [MaxCityLength];
    fread(location, MaxCityLength, 1, file);
    fclose(file);
    return location;
}

private:
unsigned short m_before;
unsigned short m_after;
unsigned short m_cityIndex;node

};測試

char* search(const char* fileName, const int& number) {
FILE* file = 0;
file = fopen(fileName, "rb");
if(file == 0) {
return (char*) "";ui

}
int count = 0;
fread(&count ,sizeof(int), 1, file);
int left = 0, right = count - 1;
Info info;    
while(left < right) {
    int middle = (left + right)/2;
    fseek(file, sizeof(int) + middle * 6 ,SEEK_SET);
    fread(&info ,sizeof(unsigned short)*3, 1, file);
    if(number < info.getBegin()) {
        right =middle -1;
    } else if(number >info.getBegin() + info.getNumberExceptLastTwo()) {
        left = middle +1;
    } else {
        return info.FindResult(file, count,info);
    }
}
return (char*) "";

}編碼

Handle mtc(const Arguments& args) {
HandleScope scope;
char* ret = search("AreaData.dat", args[0]->Int32Value());
return scope.Close(String::New((char*)ret));
url

}spa

void init(Handle<Object> target) {
NODE_SET_METHOD(target, "m2c", mtc);
}code

NODE_MODULE(mtc, init);ip

c.使用下面的兩條命令就OK了:

node-gyp configure 
node-gyp build

最後就會生成mtc.node文件:
編寫測試文件test.js
var mtc = require('mtc');
console.log('mtc.mtc()=',mtc.mtc(1895926))
執行:node test.js就會輸出福建廈門

全部的源文件上傳到了騰訊微雲上:
http://url.cn/Rezn0U 歡迎下載

相關文章
相關標籤/搜索