【问题标题】:Getting "Symbol Lookup Error" when calling C library from C++ (Node.js Addon)从 C++(Node.js 插件)调用 C 库时出现“符号查找错误”
【发布时间】:2014-12-16 01:50:24
【问题描述】:

我正在开发一个 Node.js 插件,它需要用 C++ 包装来自 C library 的对象,以便可以从客户端 JavaScript(用 CoffeeScript 编写)访问它们。

C++ 模块可以编译,但是当我尝试通过 Node.js JavaScript 运行它时,无法使用 symbol lookup error 调用 C 库,我在调试时遇到问题。

错误如下:
node: symbol lookup error: /var/lib/cloud9/ledscape-wrapper/wrapper/build/Release/wrapper.node: undefined symbol: ledscape_init

wrapper.node 是编译后的包,ledscape_init 是我要调用的库中的函数。

我试图跟踪代码并在多个文件中找到相关的 sn-ps。我已经删除了我认为无关的行。

# "AllFade.coffee"
@ledscape = require "./ledscape.js"
@frames[1] = @ledscape.LedscapeInit()
# "Ledscape.coffee"
wrapper = require "./build/Release/wrapper"
module.exports = wrapper

包装器.cc

extern "C" {
#include <ledscape.h>
}
#include <node.h>
#include <v8.h>
#include <node_object_wrap.h>
#include "LedscapeWrapper.h"

Handle<Value> LedscapeInit(const Arguments& args) {
    HandleScope scope;
    return scope.Close(LedscapeWrapper::NewInstance(args));
}

void InitAll(Handle<Object> exports, Handle<Object> module) {
    LedscapeWrapper::Init(module);
    NODE_SET_METHOD(exports, "LedscapeInit", LedscapeInit);
}

NODE_MODULE(wrapper, InitAll)

LedscapeWrapper.h

extern "C" {
#include <ledscape.h>
}
#include <node.h>
#include <node_object_wrap.h>
using namespace v8;

class LedscapeWrapper : public node::ObjectWrap {
    public:
        static void Init(v8::Handle<v8::Object> exports);
        static Handle<Value> NewInstance(const Arguments& args);
        inline ledscape_t* value() const { return value_; }
    private:
        explicit LedscapeWrapper(ledscape_t* value = ledscape_init(1));
        ~LedscapeWrapper();
        static Handle<Value> New(const Arguments& args);
        static v8::Persistent<v8::Function> constructor;
        ledscape_t* value_;
};

LedscapeWrapper.cpp

extern "C" {
#include <ledscape.h>
}
#include <node.h>
#include "LedscapeWrapper.h"
using namespace v8;

void LedscapeWrapper::Init(Handle<Object> exports) {
    Local<FunctionTemplate> tpl = FunctionTemplate::New(New);
    tpl->SetClassName(String::NewSymbol("LedscapeWrapper"));
    tpl->InstanceTemplate()->SetInternalFieldCount(1);
    constructor = Persistent<Function>::New(tpl->GetFunction());
    exports->Set(String::NewSymbol("LedscapeWrapper"), constructor);
}

Handle<Value> LedscapeWrapper::New(const Arguments& args) {
    HandleScope scope;
    if(args.IsConstructCall()) {
        ledscape_t* ledscape = ledscape_init(args[0]->NumberValue());
        LedscapeWrapper* obj = new LedscapeWrapper(ledscape);
        obj->Wrap(args.This());
        return args.This();
    }
    else {
        const int argc = 1;
        Local<Value> argv[argc] = { args[0] };
        return scope.Close(constructor->NewInstance(argc, argv));
    }
}

Handle<Value> LedscapeWrapper::NewInstance(const Arguments& args) {
    HandleScope scope;
    const int argc = 1;
    Handle<Value> argv[argc] = { args[0] };
    Local<Object> instance = constructor->NewInstance(argc, argv);
    return scope.Close(instance);
}

绑定.gyp

{
  "targets": [{
    "target_name": "wrapper",
    "sources": ["wrapper.cc","LedscapeWrapper.cpp","LedscapeFrameWrapper.cpp"],
    'include_dirs': ['/opt/ledscape/'],
    'link_settings': {  'library_dirs': ['/opt/ledscape']  },
  }],
}

我认为问题在于 LedscapeWrapper.cpp 中对 ledscape_init() 的调用之一,它无法找到库 (ledscape.h),但我主要不是 C/C++ 开发人员。

我试图从 GNU 或 Node 中查看 nm 工具,但它拒绝检查 .node 文件,而且我没有在网上找到任何使用指南。

【问题讨论】:

  • 您是否尝试使用"libraries": [ "/opt/ledscape/ledscape.a" ](或ledscape.so)直接链接静态/动态库,而不是使用link_settings
  • @mscdex 没有任何带有.a.so 扩展名的文件。其中任何一个都是自动生成的吗? (抱歉,我对 C/C++ 没有太多经验)
  • 你是先编译ledscape的吗?否则,您可能需要为 ledscape 创建一个 gyp 文件,然后让您的 binding.gyp 指向它作为依赖项。如果没有手动编译或设置依赖 gyp 文件,ledscape 不会链接到您的应用程序(静态或动态),因此缺少符号。
  • @mscdex 抱歉耽搁了。 "libraries": ["/opt/LED/LEDScape/ledscape.o"] 修复了第一个问题,但后来我得到了undefined symbol: pru_init,其中/opt/LED/LEDScape/ledscape.h 包含在pru.h 中。 "libraries": ["/opt/LED/LEDScape/ledscape.o", "/opt/LED/LEDScape/pru.o"] 修复了这个问题,但结果是 undefined symbol: prussdrv_init。有没有比包含更多依赖项更好的方法来解决这些问题?

标签: javascript c++ c node.js coffeescript


【解决方案1】:

出现此问题是因为实际程序找不到动态库(.so 文件)我建议创建一个动态库并将其添加到当前查找路径中,以便 /usr/lib 在 linux 中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    相关资源
    最近更新 更多