首页 > 代码库 > C++编写nodejs扩展实战

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‘:[ 

‘targetname‘:‘mtc‘ 
‘source‘:[‘mtc.cc‘] 



其中target
name是模块名,require的时候用 
source是C++源文件的名字放在binding.gyp同目录下

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():mbefore(0),mafter(0),m_cityIndex(0) {

}
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 mbefore; 
unsigned short m
after; 
unsigned short m_cityIndex;

};

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

}
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));

}

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

NODE_MODULE(mtc, init);

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 
欢迎下载