使用带有-fPIC的dlopen和dlsym编译C程序

问题描述 投票:5回答:3

我对错误的符号分辨率有疑问。我的主程序使用dlopen加载共享库,并使用dlsym加载共享库中的符号。程序和库都是用C编写的。图书馆代码

int a(int b)
{
  return b+1;
}

int c(int d)
{
  return a(d)+1;
}

为了使其在64位计算机上工作,编译时将-fPIC传递给gcc。

程序是:

#include <dlfcn.h>
#include <stdio.h>

int (*a)(int b);
int (*c)(int d);

int main()
{
  void* lib=dlopen("./libtest.so",RTLD_LAZY);
  a=dlsym(lib,"a");
  c=dlsym(lib,"c");
  int d = c(6);
  int b = a(5);
  printf("b is %d d is %d\n",b,d);
  return 0;
}

如果程序未使用-fPIC编译,则一切运行正常,但是当使用-fPIC编译程序时,它会由于分段错误而崩溃。经调查发现,崩溃是由于符号a的错误解析引起的。无论是从库还是从主程序(通过注释掉主程序中调用c()的行而获得),当调用a时都会发生崩溃。

[调用c()本身时不会出现问题,可能是因为c()不是由库本身内部调用的,而a()既是库内部使用的函数,也是库的API函数。

编译程序时,不使用-fPIC一个简单的解决方法。但这并非总是可能的,例如,当主程序的代码必须位于共享库中时。另一个解决方法是将指针重命名为其他功能。但是我找不到任何真正的解决方案。

用RTLD_NOW替换RTLD_LAZY没有帮助。

我对错误的符号分辨率有疑问。我的主程序使用dlopen加载共享库,并使用dlsym加载共享库中的符号。程序和库都是用C编写的。Library ...

c linux gcc elf dlopen
3个回答
3
投票

I 怀疑


0
投票

似乎这个问题可以在另外一种情况下发生(像我一样)。我有一个程序和几个动态链接的库。当我尝试再添加一个时,我在其中使用了static


0
投票

FWIW,当我编译为C ++并忘记名称修饰时,遇到了类似的问题。一种解决方案是使用extern "C"

© www.soinside.com 2019 - 2024. All rights reserved.