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]-&gt;IsUndefined() ? "192.168.0.147" : args[0]-&gt;StringValue() ;
const int port = args[1]-&gt;IsUndefined() ? 6379 : args[1]-&gt;NumberValue();
const struct timeval timeout =  {1,500000} ;
c = redisConnectionWithTimeout(hostname,port,timeout); //报错not declared

if( c == NULL || c-&gt;err){
	if(c){
		printf("Connection Error %s \n",c-&gt;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-&gt;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)


13 回复

要解决这个问题,我们需要确保在编译 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下的,因为在win下这个库没有支持的头文件。 linux下如何破?

我尝试打包成动态库,但是我不知道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 可以被找到。可以通过以下方式之一:

  1. 将库复制到标准位置:例如 /usr/lib 或者 /usr/local/lib
  2. 设置环境变量:运行时设置 LD_LIBRARY_PATH 包含 libhiredis.so 所在目录。
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/your/lib

通过以上步骤,你应该能够成功地在 Node.js Addon 中使用 libhiredis.so 库。

回到顶部