node.jscn-api

Node addon using n-api throws node: symbol lookup error:


I am attempting to write a C addon in Node.JS.

Here is my code so far:

#include <assert.h>
#include "../node_modules/node-api-headers/include/node_api.h"
#include "rtmpc.h"
#include <stdlib.h>

static napi_value Ping(napi_env env, napi_callback_info info) {
  //...

  double dping = RTMP_Ping(url);

  napi_value ping;
  status = napi_create_double(env, dping, &ping);
  assert(status == napi_ok);

  return ping;
}

#define DECLARE_NAPI_METHOD(name, func)                                        \
  { name, 0, func, 0, 0, 0, napi_default, 0 }

napi_value Init(napi_env env, napi_value exports) {
  napi_status status;
  napi_property_descriptor addDescriptor = DECLARE_NAPI_METHOD("ping", Ping);
  status = napi_define_properties(env, exports, 1, &addDescriptor);
  assert(status == napi_ok);
  return exports;
}

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

The interested function is RTMP_Ping.

RTMP_Ping is defined in

rtmpc.h

#ifndef RTMP_CUSTOM_HEADER
#define RTMP_CUSTOM_HEADER

double RTMP_Ping(char* url);

#endif

and implemented in

rtmpc.c

#include "../lib/librtmp/rtmp.h"

double RTMP_Ping(char* url) {
    RTMP* r = RTMP_Alloc();
    RTMP_SetupURL(r, url);
    RTMP_Init(r);
    RTMP_SendCtrl(r, 6, 0, 0);
    return 20;
}

Since I am importing RTMP_Ping in my code, why is it undefined?

Here's the full message:

node: symbol lookup error: /home/x/Desktop/code/rtmp-ping/build/Release/ping.node: undefined symbol: RTMP_Ping

Solution

  • I solved it.

    I removed rtmpc.c and rtmpc.h to simplify it a bit, but the problem still persisted, now the problem was with the librtmp library.

    The thing is, in node-gyp, each source needs to be included in the sources array.

    To solve this, I added a binding inside the librtmp folder in my project:

    I called it librtmp.gyp:

    {
      'targets': [
        {
          'target_name': 'librtmp',
          'type': 'static_library',
          'sources': [
            'amf.c',
            'hashswf.c',
            'log.c',
            'parseurl.c',
            'rtmp.c'
          ],
        },
      ],
    }
    

    Then, there's my binding for the ping.c source, which includes the dependency on librtmp, binding.gyp:

    {
      "targets": [
        {
          'dependencies': [
            'lib/librtmp/librtmp.gyp:librtmp',
          ],
          "target_name": "ping",
          "sources": [ 
            "src/ping.c" 
          ],
          'include_dirs': [
            'lib/librtmp'
          ]
        }
      ],
    }