Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting "Symbol Lookup Error" when calling C library from C++ (Node.js Addon)

I am working on a Node.js addon that needs to wrap the objects from a C library in C++ so they can be accessed from client-side JavaScript (written in CoffeeScript).

The C++ module compiles, but when I try to run it through Node.js JavaScript, the C library fails to be called with a symbol lookup error that I'm having problems debugging.

The error is below:
node: symbol lookup error: /var/lib/cloud9/ledscape-wrapper/wrapper/build/Release/wrapper.node: undefined symbol: ledscape_init

wrapper.node is the compiled package, ledscape_init is the function in the library I am trying to call.

I've tried to trace the code and find the relevant snippets across multiple files. I've dropped lines I've deemed extraneous.

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

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

binding.gyp

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

I think the problem is in one of the calls to ledscape_init() inside LedscapeWrapper.cpp, and that it is unable to find the library (ledscape.h), but I'm not primarily a C/C++ developer.

I tried to look into the nm tool, either from GNU or Node, but it refused to examine the .node file, and I wasn't finding any usage pointers online.

like image 281
Ryan Leonard Avatar asked Nov 22 '22 10:11

Ryan Leonard


1 Answers

This issue happens because, the actual programme cannot find the dynamic library(.so file) What i am suggest is make a dynamic library and add it to the ,current lookup path such that /usr/lib in linux

like image 199
Randika Avatar answered Dec 07 '22 01:12

Randika