【问题标题】:Undefined References After Linking Against Static Library链接静态库后未定义的引用
【发布时间】:2013-05-22 16:06:03
【问题描述】:

我编写了一个简单的程序来测试 xdotool 是否可以满足我的要求。 (嗯,不是真的。我的第一步是确定我是否可以调用 xdotool 库。)

#include <xdo.h>
#include <iostream>

using namespace std;

int main(){
    cout << xdo_version() << endl;
    xdo_new(NULL);
    return 0;
}

但是,当我使用 g++ -o a main.cpp libxdo.a -lXtst -lX11 -lXinerama -I ../test/xdotool-2.20110530.1 编译它时,我收到以下错误消息:

/tmp/ccW95RQx.o: In function `main':
main.cpp:(.text+0x5): undefined reference to `xdo_version()'
main.cpp:(.text+0x29): undefined reference to `xdo_new(char*)'
collect2: error: ld returned 1 exit status
make: *** [sendkey] Error 1

我没有使用 apt-get install 的开发包,因为它安装了一个动态库。所以,我做了一个 apt-get 源码并自己构建了这个库。我通过执行以下命令验证了 xdo_version 和 xdo_new 是静态库中定义的函数:

$ nm libxdo.a | grep xdo_version
00000000000002b0 T xdo_version
$ nm libxdo.a | grep xdo_new
0000000000004070 T xdo_new
0000000000003c90 T xdo_new_with_opened_display

如果我没记错的话,符号名称旁边的T表示该函数已定义。

总之,我试图让上面的 C++ sn-p 编译成功并静态链接到 xdotool,但遇到了一些如上所述的错误。

【问题讨论】:

    标签: linux linker g++ static-libraries xdotool


    【解决方案1】:

    提示:如果链接器显示一个函数的签名,那么它就知道该函数的签名。这是什么意思?这意味着它在编译时以某种方式编码在函数名称中,即。 e.你是 C++ 的受害者name mangling

    似乎xdo.h 标头不包含针对将 C 代码编译为 C++ 的情况的保护措施。自己手动将函数声明为extern "C",然后重新编译,就可以了。

    【讨论】:

      【解决方案2】:

      以下是在 g++ 上使用动态库的一些指导,从编码到运行。

      应用程序代码 main.cpp

      #include <iostream>
      
      using namespace std;
      
      extern "C" int funct(const int in);
      
      int main(int argc, char** args){
      
          cout << "test message " << funct(5) << endl;
          return 0;
      }
      

      函数代码 libtest.cpp

      #include <iostream>
      
      using namespace std;
      
      extern "C" int funct(const int in){
          return in*in;
      }
      

      构建 .so 文件 libtest.so

      g++ -fPIC -c libtest.cpp
      g++ -shared -o libtest.so libtest.o
      

      构建应用程序 main

      g++ -L. main.cpp -o main -ltest
      

      正在运行的应用程序 设置环境变量

      @bash: 导出 LD_LIBRARY_PATH=:$LD_LIBRARY_PATH

      @tcsh: setenv LD_LIBRARY_PATH :$LD_LIBRARY_PATH

      运行!!!

      ./main
      test message 25
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-11
        • 1970-01-01
        • 1970-01-01
        • 2015-01-24
        • 2011-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多