如何使用.so文件运行c程序

时间:2016-01-25 11:52:36

标签: c gcc go shared-libraries shared-objects

我已经浏览了stackoverflow上的所有解决方案,并询问了ubuntu。

我有一个go程序

package main

import "C"

//export Getint
func Getint() int {
        return  2
}

func main() {}

我生成了.so文件,名称为t.so,头文件为t.h

现在我想在我的C程序中使用此功能。 我已经编写了代码,但我不知道如何执行它。

#include <stdio.h>
#include <t.h>
int main()
{
int a;
a=Getint();
printf("number : %d",a);
return 0;
}

当我用

执行它时
gcc c.c t.so

它会生成一个.out文件

但是在使用./a.out运行a.out时会出现错误

./a.out
Error while loading shared libraries: t.so: can not open shared object file: no such file or directory exists.

然后我尝试了

gcc -c c.c -l t.so

因此它会生成c.o文件而且不可执行。

4 个答案:

答案 0 :(得分:9)

您应该使用linker option -rpath,它告诉链接器在可执行程序中添加信息,以便在哪里找到.so文件等运行时库。

这可以使用GCC选项-Wl来完成,该选项指示GCC前端程序将选项传递给链接器:

$ gcc c.c t.so -Wl,-rpath=$(pwd)

这会将-rpath=$(pwd)传递给链接器,$(pwd)会导致shell调用pwd命令返回当前目录。

只要您不移动库,程序就可以运行。

也可以使用环境变量LD_LIBRARY_PATH,但它是not recommended

答案 1 :(得分:3)

很可能你的加载程序找不到库。在运行二进制文件之前,尝试将路径放到libarry所在的目录LD_LIBRARY_PATH

export LD_LIBRARY_PATH=/path/to/my/library
./a.out

答案 2 :(得分:2)

您应该使用LD_LIBRARY_PATH让动态链接器在列表中找到您的共享库。语法类似于PATH:分隔的目录列表。

在OSX上,此环境变量称为DYLD_LIBRARY_PATH

答案 3 :(得分:2)

.so文件是共享对象,意味着对所有需要它们的应用程序可用的对象..即共享。由于这种特性,它们需要存储在众所周知的地方。此外,它们需要由动态链接器索引。

在Linux中,例如,您通常有一个文件 /etc/ld.so.conf ,其中存储了自动读取共享对象的所有目录

所以你的选择是:

  • 将您的共享对象文件放在一个众所周知的地方
  • 将您的共享对象文件放在您选择的位置,让动态链接器知道它:在linux中,您可以修改 ld.so.conf 并运行 ldconfig 更新ld索引
  • 正如其他建议在env变量LD_LIBRARY_PATH中写入.so的路径(因为动态链接器在运行应用程序之前读取它)。这必须在每个环境创建时完成
  • 正如其他建议在编译时使用-rpath。请注意,通过这种方式,您无法在编译后移动.so文件

我个人更喜欢在系统库路径中安装.so文件