2

我是 linux 新手,在使用动态库进行编译时出现分段错误错误。

我有两个文件

ctest1.c

void ctest1(int *i)
{ 
   *i =10;
}

ctest2.c

void ctest2(int *i)
{ 
   *i =20;
}

我已使用以下命令将这两个文件编译到名为 libtest.so 的共享库中

  gcc -shared -W1,-soname,libtest.so.1 -o libtest.so.1.0.1 ctest1.o ctest2.o -lc

我写了另一个程序 prog.c,它使用了这个库导出的函数

程序.c

#include <stdio.h>

void (*ctest1)(int*);
void (ctest2)(int*);


int main()
{
  int a;

  ctest1(&a);

  printf("%d",a);

  return 0;

}

当我使用以下命令构建可执行文件时

gcc -Wall prog.c -L。-o 编

但是当我运行生成的可执行文件时,我得到了 SegmentationFault 错误。

当我用 ldd 检查 prog 的标题时,它显示

linux-vdso.so.1 => (0x00007f99dff000) libc.so.6 => /lib64/libc.so.6 (0x0007feeaa8c1000) /lib64/ld-linux-x86-64.so.2 (0x00007feeaac1c000)

有人可以告诉问题是什么

4

3 回答 3

6

您没有调用 ctest1.c 或 ctest2.c。相反,您在 prog.c 中创建了 ctest1 和 ctest2 函数指针,而您并未对其进行初始化,因此当您尝试调用它们时会导致分段错误。

您需要声明您的函数,以便 prog.c 可以看到它们,然后将 prog.c 链接到库(可能使用 gcc 的 -l 选项)。

#include <stdio.h>

extern void ctest1(int*);
extern void ctest2(int*);


int main()
{
  int a;

  ctest1(&a);

  printf("%d",a);

  return 0;

}

和类似的东西:

gcc -Wall -L. -ltest prog.c -o prog
于 2010-04-26T04:45:23.240 回答
1

在使用 WhirlWind 给你的信息后试试这个(以“#”开头的行是注释;你不需要输入它们):

# Ensure that any shared objects you use are available in the current directory.
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

# Compile the library with a real name of "libctest.so.1.0.1"
# and a soname of "libctest.so.1".
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0.1 ctest1.o ctest2.o

# Create a symbolic link with soname as the name that points to the library.
# (libctest.so.1 -> libctest.so.1.0.1)
/sbin/ldconfig -v -n .

# Create a symbolic link using the "linker name" that points to the newly
# created library.
ln -sf libctest.so.1 libctest.so

# Compile your program.
gcc -Wall -L. prog.c -o prog -l ctest

# Run your program (it won't work without setting LD_LIBRARY_PATH because
# it won't be able to find your library).
./prog

这对我有用。看起来工作量很大,但经过几次反复试验后,我认为这几乎成了家常便饭。

您可以在http://www.ibm.com/developerworks/library/l-shobj/找到更多信息。:)

编辑:我几乎忘了提到似乎很多教程建议使用 -fPIC 选项来生成与位置无关的代码(不要将它与 -fpic 混淆,因为这会使您生成的库的可移植性降低)。拥有它并没有什么坏处,但为了简单起见,我从上面的行中省略了它。

于 2010-04-26T05:57:29.343 回答
-4

linux 中的 .so 库是动态链接的。您需要使用 prog.c 中的 dlopen() 打开 .so 文件,找到符号,然后通过函数指针调用 ctest1() 和 ctest2()。

于 2010-04-26T05:02:32.093 回答