如何 运行 c 程序与 .so 文件
How to run c program with .so file
我已经浏览了 Whosebug 上的所有解决方案以及 Ask Ubuntu。
我有一个 Go 程序:
package main
import "C"
//export Getint
func Getint() int {
return 2
}
func main() {}
并且我生成了 .so
同名文件 t.so and header file
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
它生成 a.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
文件并且不可执行。
很可能是您的加载程序找不到该库。尝试将 libarry 所在目录的路径放在 LD_LIBRARY_PATH
之前 运行 你的二进制文件。
export LD_LIBRARY_PATH=/path/to/my/library
./a.out
您应该使用 LD_LIBRARY_PATH
让动态链接器在列表中找到您的共享库。语法类似于 PATH
由 :
.
分隔的目录列表
在 OSX 上,此环境变量被称为 DYLD_LIBRARY_PATH
。
您应该使用 linker option -rpath
,它告诉链接器在可执行程序中添加信息,在哪里可以找到像您的 .so
文件这样的运行时库。
这可以使用 GCC 选项 -Wl
来完成,该选项指示 GCC 前端程序将选项传递给链接器:
$ gcc c.c t.so -Wl,-rpath=$(pwd)
这会将 -rpath=$(pwd)
传递给链接器,并且 $(pwd)
导致 shell 调用 pwd
命令到 return 当前目录。
只要您不移动库,该程序就可以运行。
您也可以使用环境变量LD_LIBRARY_PATH
,但它是not recommended。
.so 文件是共享对象,意思是所有需要它们的应用程序都可以使用的对象.. 即共享。由于这个特性,它们需要存放在一个众所周知的地方。此外,它们需要被动态链接器索引。
例如,在 linux 中,您通常有一个文件 /etc/ld.so.conf,其中自动读取共享对象的所有目录都是存储
所以你的选择是:
- 将您的共享对象文件放在一个众所周知的地方
- 把你的共享目标文件放在你选择的地方,让动态链接器知道它:在linux你可以修改ld.so.conf 和 运行 ldconfig 更新 ld 索引
- 正如其他人所建议的那样,在环境变量 LD_LIBRARY_PATH 中写入 .so 的路径(因为动态链接器会在 运行 应用程序之前读取它)。这必须在每次创建环境时完成
- 正如其他人建议的那样,编译时使用 -rpath。请注意,这样你不能在编译后移动你的.so文件
个人比较喜欢将.so文件安装在系统库路径下
我已经浏览了 Whosebug 上的所有解决方案以及 Ask Ubuntu。
我有一个 Go 程序:
package main
import "C"
//export Getint
func Getint() int {
return 2
}
func main() {}
并且我生成了 .so
同名文件 t.so and header file
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
它生成 a.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
文件并且不可执行。
很可能是您的加载程序找不到该库。尝试将 libarry 所在目录的路径放在 LD_LIBRARY_PATH
之前 运行 你的二进制文件。
export LD_LIBRARY_PATH=/path/to/my/library
./a.out
您应该使用 LD_LIBRARY_PATH
让动态链接器在列表中找到您的共享库。语法类似于 PATH
由 :
.
在 OSX 上,此环境变量被称为 DYLD_LIBRARY_PATH
。
您应该使用 linker option -rpath
,它告诉链接器在可执行程序中添加信息,在哪里可以找到像您的 .so
文件这样的运行时库。
这可以使用 GCC 选项 -Wl
来完成,该选项指示 GCC 前端程序将选项传递给链接器:
$ gcc c.c t.so -Wl,-rpath=$(pwd)
这会将 -rpath=$(pwd)
传递给链接器,并且 $(pwd)
导致 shell 调用 pwd
命令到 return 当前目录。
只要您不移动库,该程序就可以运行。
您也可以使用环境变量LD_LIBRARY_PATH
,但它是not recommended。
.so 文件是共享对象,意思是所有需要它们的应用程序都可以使用的对象.. 即共享。由于这个特性,它们需要存放在一个众所周知的地方。此外,它们需要被动态链接器索引。
例如,在 linux 中,您通常有一个文件 /etc/ld.so.conf,其中自动读取共享对象的所有目录都是存储
所以你的选择是:
- 将您的共享对象文件放在一个众所周知的地方
- 把你的共享目标文件放在你选择的地方,让动态链接器知道它:在linux你可以修改ld.so.conf 和 运行 ldconfig 更新 ld 索引
- 正如其他人所建议的那样,在环境变量 LD_LIBRARY_PATH 中写入 .so 的路径(因为动态链接器会在 运行 应用程序之前读取它)。这必须在每次创建环境时完成
- 正如其他人建议的那样,编译时使用 -rpath。请注意,这样你不能在编译后移动你的.so文件
个人比较喜欢将.so文件安装在系统库路径下