Search code examples
c++node.jsnode-gypgypnode-addon-api

Use stdlib and rand with Node native module (node-gyp)


This is just an example of the problem.

Let's say I have utils.cc

#include "../headers/utils/utils.h"

double sum()
{
    double result = 1 + 1;
    return result;
}

double multisum(int n)
{
    double result = 0;
    for (int i = 0; i < n; i++)
    {
        result += rand();
    }
    return result;
}

and this file that uses it

#include "../headers/modules/sum.h"
#include "../headers/utils.h"

/* HELPERS DECLARATION */

static void ReturnResult(int result, const FunctionCallbackInfo<Value> &args);

/* EXPORTED IMPLEMENTATION */

void Sum(const FunctionCallbackInfo<Value> &args)
{
    double result = sum();
    ReturnResult(result, args);
}
void Multisum1e7(const FunctionCallbackInfo<Value> &args)
{
    int result = multisum(1e7);
    ReturnResult(result, args);
}

/* HELPERS IMPLEMENTATION */

static void ReturnResult(double result, const FunctionCallbackInfo<Value> &args)
{
    Isolate *isolate = args.GetIsolate();
    args.GetReturnValue().Set(Number::New(isolate, result));
}

These functions are then exported with <node.h>.

The problem is in the rand() function. The code compiles (I have included stdlib in the code) and this is the binding.gyp:

{
  "targets": [
    {
      "target_name": "addon",
      "sources": [
        "addon/main.cc",
        "addon/utils.cc",
        "addon/modules/sum.cc"
      ]
    }
  ]
}

But at runtime I got this error:

node: symbol lookup error: /xxx/build/Release/addon.node: undefined symbol: _ZL12ReturnResultiRKN2v820FunctionCallbackInfoINS_5ValueEEE

That disappears if I don't use rand();


Solution

  • You forward declare your helper function like this:

    static void ReturnResult(int result, const FunctionCallbackInfo<Value> &args);
    //                       ^^^
    

    but then implement it like this:

    static void ReturnResult(double result, const FunctionCallbackInfo<Value> &args)
    //                       ^^^^^^
    

    So fix whichever one is wrong and your problem should go away.


    You might like to know about demangler.com. That would have told you that the mangled symbol in your linker error corresponds to:

    ReturnResult(int, v8::FunctionCallbackInfo<v8::Value> const&)

    which I imagine would have been helpful.