You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用N-API开发Node.js C扩展报错:RTMP_Ping符号未定义

Node.js C扩展:undefined symbol: RTMP_Ping 问题排查与解决

问题背景

开发Node.js C扩展时,调用自定义的RTMP_Ping函数出现运行时错误:

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

相关代码如下:

主扩展文件(ping.c)

#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)

头文件(rtmpc.h)

#ifndef RTMP_CUSTOM_HEADER
#define RTMP_CUSTOM_HEADER

double RTMP_Ping(char* url);

#endif

实现文件(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;
}

问题原因

核心原因是编译构建时未将rtmpc.c的目标文件链接到最终的.node动态库中,导致RTMP_Ping的符号没有被包含在扩展模块里,Node.js加载时无法找到该符号。

此外还有两种次要可能:

  • C/C编译的名字修饰不匹配(如果用C编译器编译C代码)
  • 函数声明与实现的签名不一致

解决方案

1. 修正binding.gyp配置

确保binding.gyp的sources数组包含所有需要编译的C文件,同时正确链接依赖的librtmp库。示例配置:

{
  "targets": [
    {
      "target_name": "ping",
      "sources": [ "ping.c", "rtmpc.c" ],
      "include_dirs": [
        "<!(node -p \"require('node-api-headers').include_dir\")",
        "./lib/librtmp"
      ],
      "libraries": [ "-L./lib/librtmp -lrtmp" ]
    }
  ]
}
  • sources:必须包含ping.c和rtmpc.c,缺任意一个都会导致对应符号缺失
  • include_dirs:指定头文件路径,保证能找到node-api和librtmp的头文件
  • libraries:链接librtmp静态/动态库,避免RTMP_Alloc等底层函数符号缺失

2. 重新编译扩展

修改配置后,清理旧构建产物并重新编译:

node-gyp clean
node-gyp configure build

3. 处理C/C++名字修饰问题(可选)

如果你的扩展使用C编译器编译,需要在rtmpc.h中添加extern "C"声明,防止C对函数名进行修饰:

#ifndef RTMP_CUSTOM_HEADER
#define RTMP_CUSTOM_HEADER

#ifdef __cplusplus
extern "C" {
#endif

double RTMP_Ping(char* url);

#ifdef __cplusplus
}
#endif

#endif

4. 校验函数签名一致性

确认rtmpc.h中的声明和rtmpc.c中的实现完全匹配,包括返回值类型、参数类型和数量,避免因签名不一致导致符号不匹配。

内容的提问来源于stack exchange,提问作者violetflare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 22:04:51