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

huangapple go评论86阅读模式
英文:

How to run c program with .so file

问题

我已经阅读了StackOverflow和Ask 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

它会生成a.out文件。

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

./a.out
Error while loading shared libraries: t.so: cannot open shared object file: No such file or directory exists.

然后我尝试了以下命令:

gcc -c c.c -l t.so

这样会生成c.o文件,但它不可执行。

英文:

I have gone through all the solutions on StackOverflow as well as Ask Ubuntu.

I have a Go program:

package main

import &quot;C&quot;

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

func main() {}

and I have generated .so file for the same with name t.so and header file t.h`

Now I would like to use this function in my C program.
I have written the code but I don't know how to execute it.

#include &lt;stdio.h&gt;
#include &lt;t.h&gt;
int main()
{
int a;
a=Getint();
printf(&quot;number : %d&quot;,a);
return 0;
}

When I execute it with

gcc c.c t.so

it generates a.out file

but at the time of running a.out with ./a.out it gives an error:

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

then I tried with:

gcc -c c.c -l t.so

So it generates c.o file and it is not executable.

答案1

得分: 11

你应该使用链接器选项-rpath,告诉链接器在可执行程序中添加信息,以便找到运行时库,比如你的.so文件。

可以使用GCC选项-Wl来实现,它指示GCC前端程序将选项传递给链接器:

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

这将向链接器传递-rpath=$(pwd),而$(pwd)会调用shell来执行pwd命令,返回当前目录。

只要不移动库文件,程序就应该可以正常工作。


你也可以使用环境变量LD_LIBRARY_PATH,但这并不被推荐使用。

英文:

You should use the linker option -rpath, which tells the linker to add information in the executable program where to find runtime libraries like your .so file.

This can be done using the GCC option -Wl which instructs the GCC frontend program to pass an option to the linker:

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

This will pass -rpath=$(pwd) to the linker, and $(pwd) causes the shell to call the pwd command to return the current directory.

As long as you don't move the library the program should work.


You can use the environment variable LD_LIBRARY_PATH too, but it's not recommended.

答案2

得分: 5

很可能是你的加载器找不到库文件。尝试在运行可执行文件之前将库文件所在的目录路径添加到LD_LIBRARY_PATH环境变量中。

export LD_LIBRARY_PATH=/path/to/my/library
./a.out
英文:

Most probably your loader cannot find the library. Try to put the path to the directory where the libarry is located to LD_LIBRARY_PATH prior to run your binary.

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

答案3

得分: 2

.so文件是共享对象,意味着它们可供所有需要它们的应用程序使用,也就是说它们是共享的。由于这个特性,它们需要存储在一个众所周知的位置。此外,它们需要被动态链接器索引。

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

所以你有以下几个选择:

  • 将你的共享对象文件放在一个众所周知的位置。
  • 将你的共享对象文件放在你选择的位置,并让动态链接器知道它:在Linux中,你可以修改ld.so.conf并运行ldconfig来更新ld索引。
  • 如其他人建议的,在环境变量LD_LIBRARY_PATH中写入你的.so文件的路径(因为动态链接器在运行你的应用程序之前会读取它)。这必须在每次创建环境时进行。
  • 如其他人建议的,在编译时使用-rpath选项。请注意,这样做后,你不能移动编译后的.so文件。

个人而言,我更喜欢将.so文件安装在系统库路径中。

英文:

.so files are shared object, meaning object that are available to all applications that need them.. that is, shared. Due to this characteristics, they need to be stored in a well known place. Also, they need to be indexed by the dynamic linker.

In linux for instance you typically have a file /etc/ld.so.conf where all directories where shared object are automatically read from are stored

So your options are:

  • Put your shared object file in a well known place
  • Put your shared object file in a place of your choice and let the dynamic linker know about it: in linux you can modify ld.so.conf and run ldconfig to update ld indexes
  • As other suggested write the path of your .so in the env variable LD_LIBRARY_PATH (since dynamic linker reads it before running your application). This must be done at each environment creation
  • As other suggested use -rpath when compiling. Note that in this way you cannot move your .so file after the compilation

Personally I prefer installing the .so file in a system library path

答案4

得分: 1

你应该使用LD_LIBRARY_PATH来让动态链接器在列表中找到你的共享库。语法类似于PATH,是由冒号分隔的目录列表。

在OSX上,这个环境变量被称为DYLD_LIBRARY_PATH

英文:

You should use LD_LIBRARY_PATH to let the dynamic linker find your shared library in the list. Syntax is similar to PATH a list of directories separted by :.

On OSX this environment variable is called DYLD_LIBRARY_PATH.

huangapple
  • 本文由 发表于 2016年1月25日 19:52:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/34991934.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定