node.js中的未定义符号Linux下的C++插件,为什么?

Xad*_*laX 2 javascript c++ linux v8 node.js

我是在node.js中编写C++插件的新手.

这是我的模块:

$ npm install simpleini
Run Code Online (Sandbox Code Playgroud)

它基于miniini-0.9.我的来源是src/simpleIni.cc.我在Windows,OS X,Linux(Debian)下尝试过这个模块.它在Windows和OS X下运行良好.

但是当我在Linux中运行时,看起来:

node: symbol lookup err: .../simpleIni.node: undefined symbol: _ZNK10INISection10ReadStringEPKcRS1_
Run Code Online (Sandbox Code Playgroud)

为什么?

jsa*_*der 6

经过一番搜索,这是我发现的.

这样做:

$ nm -C build/Release/simpleIni.node  | grep ReadString
                 U INISection::ReadString(char const*, char const*&) const
00000000000032b0 t INISection::ReadString(char const*, char const*&) const [clone .part.11]
0000000000003f80 W INISection::ReadString(std::string const&, std::string&) const
00000000000081a0 T INISection::ReadStrings(char const*, char const**, unsigned int) const
0000000000008f20 T INISection::ReadStrings(std::string const&, std::vector<std::string, std::allocator<std::string> >&) const
000000000000bca0 r INISection::ReadString(char const*, char const*&) const::__PRETTY_FUNCTION__
000000000000b8a0 r INISection::ReadStrings(char const*, char const**, unsigned int) const::__PRETTY_FUNCTION__
Run Code Online (Sandbox Code Playgroud)

所以关键是

                 U INISection::ReadString(char const*, char const*&) const
Run Code Online (Sandbox Code Playgroud)

这看起来像未定义的......虽然有另一个符号副本

00000000000032b0 t INISection::ReadString(char const*, char const*&) const [clone .part.11]
Run Code Online (Sandbox Code Playgroud)

现在我们可以在您的代码中搜索此方法:

在src/miniini-0.9/miniini/include/inisection.h

class INISection
{
...
        bool ReadString(const char * const name, const char * & out) const;
}
Run Code Online (Sandbox Code Playgroud)

并在src/miniini-0.9/miniini/src/inisection.cpp中

inline bool INISection::ReadString(const char * name, const char * & out) const
{
...
}
Run Code Online (Sandbox Code Playgroud)

现在关键是这个内联.根据C++ FAQ 如何告诉编译器使内联成员函数?

您(几乎总是)将内联函数的定义({...}部分)放在头文件中的原因是为了避免链接器出现"未解决的外部"错误.如果将内联函数的定义放在.cpp文件中,并且从某个其他.cpp文件调用该函数,则会发生该错误.

从inisection.cpp中删除内联并重建我们可以再次尝试nm

$ nm -C build/Release/simpleIni.node  | grep ReadString
00000000000069a0 T INISection::ReadString(char const*, char const*&) const
0000000000003f70 W INISection::ReadString(std::string const&, std::string&) const
00000000000080e0 T INISection::ReadStrings(char const*, char const**, unsigned int) const
0000000000008d20 T INISection::ReadStrings(std::string const&, std::vector<std::string, std::allocator<std::string> >&) const
000000000000bc20 r INISection::ReadString(char const*, char const*&) const::__PRETTY_FUNCTION__
000000000000b7e0 r INISection::ReadStrings(char const*, char const**, unsigned int) const::__PRETTY_FUNCTION__
Run Code Online (Sandbox Code Playgroud)

这次没有未定义的符号,ReadString只出现一次.