Nodejs addon 如何添加其他动态库
Nodejs addon 如何添加其他动态库
我在github上clone了一个hiredis Repo(redis的C客户端代码) 我想在node addon 上使用这段代码做一些功能(原因是我需要在addon里头用到redis), 我已经好久没写C了,大多数的内容都还给老师了,好不容易成功编译出来,但是在nodejs上就不行,因为没办法链接上一个叫libhiredis.so的动态库(事实上我是不知道如何在nodejs上配置链接)。
各位高人,可以帮助下我吗?
另外贴一下代码:
#include <node.h>
#include <v8.h>
#include “hiredis.h” //这里我可以索性写一个绝对地址
using namespace v8;
Handle<Value> ValueQuene(const Arguments& args){
HandleScope scope;
redisContent *c; //由于没有链接so,所以这段是报错的,没生命
redisReply *reply; //报错not declared
const char *hostname = args[0]->IsUndefined() ? "192.168.0.147" : args[0]->StringValue() ;
const int port = args[1]->IsUndefined() ? 6379 : args[1]->NumberValue();
const struct timeval timeout = {1,500000} ;
c = redisConnectionWithTimeout(hostname,port,timeout); //报错not declared
if( c == NULL || c->err){
if(c){
printf("Connection Error %s \n",c->errstr);
redisFree(c);//报错not declared
}else{
printf("UnKnow Error \n");
}
return scope.close(Error::New("Error!!"));
}
reply = redisCommand(c,"PING");//报错not declared
char* pong = reply->str;
freeReplyObject(reply);//报错not declared
redisFree(c);//报错not declared
return scope.Close(String::NewSymbol(pong));
}
void init(Handle<Object> exports) {
exports->Set(String::NewSymbol(“ValueQuene”),
FunctionTemplate::New(ValueQuene)->GetFunction());
}
NODE_MODULE(ValueQuene, init)
要解决这个问题,我们需要确保在编译 Node.js Addon 时正确地链接 libhiredis
动态库。以下是具体的步骤和示例代码:
步骤 1: 确保 hiredis
库已安装
首先,你需要确保 hiredis
库已经安装在你的系统中。如果没有安装,可以使用以下命令进行安装:
sudo apt-get install libhiredis-dev
步骤 2: 修改 C++ 代码以包含正确的头文件和库
我们需要修改 C++ 代码,使其能够正确引用 hiredis
的头文件和函数。
示例代码
#include <node.h>
#include <v8.h>
#include <hiredis/hiredis.h> // 包含 hiredis 头文件
using namespace v8;
Handle<Value> ValueQuene(const Arguments& args) {
HandleScope scope;
const char* hostname = args[0]->IsUndefined() ? "192.168.0.147" : args[0]->ToString()->Utf8Value().get();
const int port = args[1]->IsUndefined() ? 6379 : args[1]->Int32Value();
struct timeval timeout = {1, 500000};
redisContext *c = redisConnectWithTimeout(hostname, port, timeout);
if (c == NULL || c->err) {
if (c) {
printf("Connection Error %s\n", c->errstr);
redisFree(c);
} else {
printf("Unknown Error\n");
}
return scope.Close(Exception::Error(String::New("Error!!")));
}
redisReply *reply = reinterpret_cast<redisReply*>(redisCommand(c, "PING"));
std::string pong = reply->str;
freeReplyObject(reply);
redisFree(c);
return scope.Close(String::New(pong.c_str()));
}
void init(Handle<Object> exports) {
exports->Set(String::NewSymbol("valueQuene"),
FunctionTemplate::New(ValueQuene)->GetFunction());
}
NODE_MODULE(valueQuene, init)
步骤 3: 编译 Node.js Addon
在编译 Node.js Addon 时,需要指定链接 libhiredis
库。你可以通过在 binding.gyp
文件中添加链接器标志来实现这一点。
binding.gyp 文件
{
"targets": [
{
"target_name": "valueQuene",
"sources": [ "valueQuene.cc" ],
"libraries": ["-lhiredis"],
"include_dirs": ["<!@(pkg-config --cflags-only-I hiredis | sed s/-I//g)"]
}
]
}
步骤 4: 构建并安装
运行以下命令构建和安装 Node.js Addon:
node-gyp configure
node-gyp build
使用 Node.js Addon
最后,在你的 Node.js 脚本中使用这个模块:
const addon = require('./build/Release/valueQuene');
console.log(addon.valueQuene('127.0.0.1', 6379));
这样,你就可以在 Node.js Addon 中使用 hiredis
库了。希望这些步骤能帮助你解决问题!
HINSTANCE hDLL; hDLL=LoadLibrary(“dlldemo.dll”);//加载动态链接库dlldemo.dll文件; typedef int(*pMax)(int a,int b);//函数指针 pMax Max=NULL; Max=(pMax)GetProcAddress(hDLL,“Max”); 这是windows上VC++的代码,http://cnodejs.org/topic/51c2ba5c73c638f3703e4185
我的做法是编译成静态库拉进来,整体打包成 node addon
你好,能否在我的代码基础上进行修改呢? 在linux下gcc编译一个文件是使用gcc xxx.c -I /home/xxx/github/hiredis /home/xxx/github/hiredis/libhiredis.so -o xxx 但在node-gyp里头我就不会配置了,一直报问题,但是我就不会修改,能否帮我修改下?
我尝试打包成动态库,但是我不知道linux下如何引入
最终你这个.so文件还是要打包到模块里面去的啊,不如编译成静态库,可以直接在 bind.gyp 里面引入,不然动态库的话可能需要额外用脚本连接
抱歉,我实在不太动你的意思,我不知道gyp怎么配置,能否帮我修改一下呢?或者你可否提供一个模板给我
我制作了一个静态库.a文件,但我搜索了很多资料,但实在不会配置gyp,最终build出来的错误都是一样,快崩溃了!!
大神,你不帮我解决这个问题我的项目进度卡住了。
这不简单。在binding.gyp 添加 ‘libraries’: [ ‘-lclntsh’,’-lpthread’ ], ‘link_settings’: {‘libraries’: [ ‘-L<(oci_lib_dir)/lib’] },
你好,能否留下联系方式,方便请教
为了在 Node.js Addon 中正确地链接和使用 libhiredis.so
动态库,你需要确保在编译时指定该库,并且在运行时能够找到该库。以下是如何实现这一点的步骤:
步骤 1: 编译时链接库
在你的 binding.gyp
文件中,指定 libraries
参数来链接 libhiredis.so
库。
{
"targets": [
{
"target_name": "valuequene",
"sources": [ "valuequene.cc" ],
"libraries": ["-lhiredis"],
"include_dirs": [
"<!(node -e \"require('nan')\")"
]
}
]
}
步骤 2: 修改 C++ 代码
确保你在代码中包含了正确的头文件,并且处理好所有依赖。
#include <node.h>
#include <v8.h>
// 需要包含 hiredis 的头文件
#include "hiredis/hiredis.h"
using namespace v8;
Handle<Value> ValueQuene(const Arguments& args) {
HandleScope scope;
redisContext *c;
redisReply *reply;
const char *hostname = args[0]->IsUndefined() ? "192.168.0.147" : args[0]->ToString()->Utf8Value().c_str();
const int port = args[1]->IsUndefined() ? 6379 : args[1]->Uint32Value();
struct timeval timeout = { 1, 500000 };
c = redisConnectWithTimeout(hostname, port, timeout);
if (c == NULL || c->err) {
if (c) {
printf("Connection Error %s\n", c->errstr);
redisFree(c);
} else {
printf("Unknown Error\n");
}
return scope.Close(Exception::Error(String::New("Error!!")));
}
reply = redisCommand(c, "PING");
std::string pong(reply->str, reply->len);
freeReplyObject(reply);
redisFree(c);
return scope.Close(String::New(pong.c_str()));
}
void init(Handle<Object> exports) {
exports->Set(String::NewSymbol("ValueQuene"), FunctionTemplate::New(ValueQuene)->GetFunction());
}
NODE_MODULE(valuequene, init)
步骤 3: 确保动态库可访问
确保在编译后运行时,libhiredis.so
可以被找到。可以通过以下方式之一:
- 将库复制到标准位置:例如
/usr/lib
或者/usr/local/lib
。 - 设置环境变量:运行时设置
LD_LIBRARY_PATH
包含libhiredis.so
所在目录。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/your/lib
通过以上步骤,你应该能够成功地在 Node.js Addon 中使用 libhiredis.so
库。