【问题标题】:GCC Dynamic library building problemGCC动态库构建问题
【发布时间】:2010-04-26 04:38:29
【问题描述】:

我是 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,它使用了这个库导出的函数

prog.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)

谁能告诉我是什么问题

【问题讨论】:

    标签: gcc dynamic-linking


    【解决方案1】:

    您没有调用 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
    

    【讨论】:

    • 你可以 extern void ctest1(int*);void ctest2(int*);并链接你的图书馆..它应该可以工作
    • @WhirlWind Ater 进行上述更改我收到错误“找不到 -ltest”。
    • @Sirish - 尝试使用“gcc -shared -o libtest.so ctest1.c ctest2.c”之类的简单方法构建您的共享库 - 这对我有用。
    • @WhirlWind 我已在 prog.c 中将函数声明为 extern 并按照您提到的那样构建共享库,但我仍然遇到分段错误
    • 声明void (ctest2)(int *); 只是写extern void ctest2(int *); 的一种有趣方式,它具有覆盖任何类似函数的宏ctest2 的优点,因为名称后面没有开括号。 ctest1 的定义是一个未初始化的函数指针,因此会导致 seg 错误。
    【解决方案2】:

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

    # 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 混淆,因为这会使生成的库的可移植性降低)。拥有它并没有什么坏处,但为了简单起见,我从上面的行中省略了它。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-26
        • 1970-01-01
        • 1970-01-01
        • 2013-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多