我是 C 编程新手。我对 .so 文件一无所知。它有什么需要?我怎样才能创建它?如何绑定我的 C 代码或二进制代码?如果我不制作任何 .so 文件并直接制作 C 代码的可执行二进制文件,它的优点和缺点是什么?需要对其进行详细描述。
3 回答
.so
文件是共享对象。通常共享库被制作为.so
.
通过制作一个库,.so
您可以提高内存使用效率。即,当使用该库的多个应用程序正在运行时,与静态库的情况相反,该库只加载到内存中一次。
创建动态库:
gcc -Wall -fPIC -c *.c
gcc -shared -Wl,-soname,libctest.so.1 -o libctest.so.1.0 *.o
-fPIC
: 用于输出位置无关代码的编译器指令,这是共享库所需的特性。
-shared
:生成一个共享对象,然后可以将其与其他对象链接以形成可执行文件。
您可以在此处找到更多信息。
.so
代表共享对象。在 Windows 世界中,这被称为 DLL。
您可以像使用 DLL 一样使用它——您可以将应用程序动态链接到它。
如果您的库名为 libblah.so,您可以使用 gcc 链接到它,如下所示:
gcc myprog.c -lblah -o myprog
共享库有助于将通用功能分解到单独的文件中。
但是,使用共享库会导致称为DLL Hell的现象。虽然这个问题起源于 Windows 世界,但它也适用于 Linux 系统,除非您非常关注使用的共享库的确切版本并执行严格的版本控制。例如,如果您使用共享库(甚至是系统共享库,而不是您创建的库)编译应用程序,然后您尝试在另一个 Linux 机器上运行相同的可执行文件(具有显着不同的 Linux 版本或发行版),它可能无法运行 - 因为使用的共享库不一样。
因此,如果您希望您的可执行文件可移植到最大数量的 Linux 系统而无需重新编译,那么静态编译它可能是有意义的。虽然这会使您的可执行文件更大,但它确实减少了通常归因于 DLL Hell 的问题。
除了其他答案之外,请注意,要构建共享对象(或共享库),您最好以位置无关代码模式编译相关源文件,例如
gcc -Wall -O -fPIC src.c -c -o src.pic.o
-Wall
在编译某些源代码时询问所有警告总是有用的。
然后您可以将所有这些*.pic.o
文件链接到.so
using
gcc -shared src1.pic.o src2.pic.o -o shared.so
您甚至可以libfoo.so
使用将一些共享库链接到该共享对象
gcc -shared src1.pic.o src2.pic.o -lfoo -o shared.so
最后,可以使用dlopen将共享对象动态加载到进程中;这对于获取插件很有用。(然后为它们定义一个约定并使用 获取其中的重要符号dlsym
)
另请参阅程序库 howto和Executable & Link Format & shared library wikipages
When make your shared library, better name it lib
foo.so
where foo is some arbitrary name. Then, at link time, use also the -L
option to gcc
(actually to the linker) to tell about the directory containing it, and link it using -l
foo option. For example, name your library libnewbie.so
when making it, and pass -L.
(if it is in the current directory) before -lnewbie
when linking it, e.g. gcc -Wall myprog.c -L. -lnewbie -o myprog