Linux下C文件如何编译为SO文件? (linux c文件编译so)

SO文件,即动态链接库,是一种可以在程序运行时动态加载的库文件。在Linux系统下,C语言的源代码可以编译生成SO文件,并在程序运行时动态链接到程序中。这种方式可以降低程序的体积,节省内存空间,并且方便程序扩展和更新。

本文将讲解在Linux系统下,C文件如何编译为SO文件的步骤及注意事项。

步骤1:编写C代码

需要编写C语言代码,以便在后续步骤中进行编译和链接。以下为一个简单的C语言代码示例:

“`

// hello.c

#include

void hello()

{

printf(“Hello, world!\n”);

}

“`

这个C代码非常简单,只是定义了一个函数,函数名字为`hello()`,函数的功能是输出“Hello, world!”字符串。

步骤2:编写Makefile文件

在Linux系统下,Makefile文件是用于自动化编译的重要文件。Makefile文件可以指定编译器、编译选项等参数,并定义了如何将源文件和对象文件联系在一起,生成目标文件的规则。

以下为一个样例的Makefile文件:

“`

# Makefile

CC = gcc

CFLAG = -fpic -shared

INC = -I.

all: hello.so

hello.so: hello.o

$(CC) $(CFLAG) -o $@ $

hello.o: hello.c

$(CC) $(CFLAG) $(INC) -c -o $@ $

clean:

rm -f *.o *.so

“`

以上的Makefile文件定义了以下几个目标:

– all:编译所有的目标文件

– hello.so:生成动态链接库

– hello.o:编译源码生成目标代码

– clean:清除所有的目标文件

这个Makefile文件的主要功能是将hello.c文件编译为hello.so动态链接库文件。它使用了GCC编译器,并且定义了一些编译选项和文件名。

步骤3:编译SO文件

在完成了上述两个步骤之后,就可以开始编译SO文件了。执行以下命令:

“`

make

“`

这个命令将会自动执行Makefile文件,并将源文件编译链接成SO文件。在执行完成之后,会生成一个名为hello.so的SO文件。执行以下命令查看生成的动态链接库:

“`

ls -l hello.so

“`

输出结果如下:

“`

-rw-r–r– 1 user user 2184 Mar 12 09:06 hello.so

“`

步骤4:测试动态链接库

可以测试一下刚刚生成的动态链接库。在C语言程序中,可以使用`dlopen()`函数动态加载SO文件,并使用`dlsym()`函数获取动态链接库中的函数。

以下是一个简单的测试程序:

“`

// test.c

#include

int mn()

{

void (*hello)() = NULL;

void *handle = dlopen(“./hello.so”, RTLD_LAZY);

if (handle != NULL)

{

hello = dlsym(handle, “hello”);

if (hello != NULL)

{

hello();

}

dlclose(handle);

}

return 0;

}

“`

在这个测试程序中,使用了`dlopen()`函数加载hello.so文件,并使用`dlsym()`函数获取其中的hello()函数。最后调用hello()函数,输出“Hello, world!”字符串。

执行以下命令编译测试程序:

“`

gcc -o test test.c -ldl

“`

这个命令将链接动态链接库,并生成名为test的可执行程序。

执行以下命令运行测试程序:

“`

./test

“`

如果一切顺利,将输出“Hello, world!”字符串。

注意事项

编译SO文件时,需要指定编译选项`-fpic`和`-shared`,以告诉编译器生成位置无关代码,并将生成的目标文件链接到动态链接库。这些选项能够让SO文件可以在程序运行时动态加载,而不需要重新编译。

在链接SO文件时,需要指定选项`-ldl`,以告诉编译器链接动态链接库。使用`dlopen()`和`dlsym()`函数时,需要包含头文件“。

相关问题拓展阅读:

请问我有一个.so文件,如何在Linux下编程使用呢?

Linux下的.so是基于linux下的动态链接,其功能和作用类似与windows下.dll文件。

下面是关于.so的介绍:

一、引言

通常情况下,对函数库的链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数库销亏圆(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数库再无瓜葛,因为所有需要的函数已拷贝到自己门下。所以这些函数库被成为静态库(static libaray),通常文件名为“lib.a”的形式。

其实,我们也可以把对一些库函数的链接载入推迟到程序运行的时期(runtime)。这就是如雷贯耳的动态链接空橘库(dynamic link library)技术。

二、动态链接库的特点与优势

首先让我们来看一下,把库函数推迟到程序运行时期载入的好处:

1. 可以实现进程之间的资源共享。

什么概念呢?就是说,某个程序的在运行中要调用某个动态链接库函数的时候,操作系统首先会查看所有正在运行的程序,看在内存里是否已有此库函数的拷贝了。如果有,则让其共享那一个拷贝;只有没有才链接载入。这样的模式虽然会带来一些“动态链接”额外的开销,却大大的节省了系统的内存资源。C的标准库就是动态链接库,也就是说系统中所有运行的程序共享着同一个C标准库的代码段。

2. 将一些程序升级变得简单。用户只需要升级动态链接库,而无需重新编译链接其他原有的代码就可以完成整个程序的升级。Windows 就是一个很好的例子。

3. 甚至可以真正坐到链接载入完全由程序员在程序代码中控制。

程序员在编写程序的时候,可以明确的指明什么时候或者什么情况下,链接载入哪个动态链接库函数。你可以有一个相当大的软件,但每次运行的时候,由于不同的操作需求,只有一小部分程序被载入内存。所有的函数本着“有需求才调入”的原则,于是大大节省了系统资源。比如现在的软件通常都能打开若干种不同类型的文件,这些读写操作通常都用动态链接库来实现。在一次运行当中,一般只有一种类型的文件将会被打开。所以直到程序知道文件的类型以后再载入相应的读写函数,而不是一开始就将所有的读写函数都载入,然后才发觉在整个程序中根本没有用到它们。

三、动态链接库的创建

由于动态链接库函数的共享特性,它们不会被拷贝到可执行文件中。在编译的时候,编译器只会做一些函数名之类的检查。在程序运行的时候,被调用的动态链接库函数被安置在内存的某个地方,所有调用它的程序将指向这个代码段。因此,这些代码必须实用相对地址,而不是绝对地址。在编译的时候,我们需要告诉编译器,这些对象文件是用来做动态链接库的,所以要用地址不无关代码(Position Independent Code (PIC))。

对gcc编译器,只需添加上 -fPIC 标签,如:

gcc -fPIC -c file1.c

gcc -fPIC -c file2.c

gcc -shared lib.so file1.o file2.o

注意到最后一行,-shared 标签告诉编译器这是要建立动态链接库。这与静态链接库的建立很不一样,后者用的是 ar 命令。也注意到,动态链接库亏塌的名字形式为 “lib.so” 后缀名为 “.so”

四、动态链接库的使用

使用动态链接库,首先需要在编译期间让编译器检查一些语法与定义。

这与静态库的实用基本一样,用的是 -Lpath 和 -l 标签。如:

gcc file1.o file2.o -Lpath -l -o program.exe

编译器会先在path文件夹下搜索lib.so文件,如果没有找到,继续搜索lib.a(静态库)。

在程序运行期间,也需要告诉系统去哪里找你的动态链接库文件。在UNIX下是通过定义名为 LD_LIBRARY_PATH 的环境变量来实现的。只需将path赋值给此变量即可。csh 命令为:

setenv LD_LIBRARY_PATH   your/full/path/to/dll

一切安排妥当后,你可以用 ldd 命令检查是否连接正常。

ldd program.exe

动态链接库*.so的编译与使用- –

动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态库链接库而苦恼的兄弟们提供一点帮助。

1、动态库的编译

下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。

so_test.h:

#include   “stdio.h”

void test_a();

void test_b();

void test_c();

test_a.c:

#include “so_test.h”

void test_a()

{

printf(“this is in test_a…/n”);

}

test_b.c:

#include “so_test.h”

void test_b()

{

printf(“this is in test_b…/n”);

}

test_a.c:

#include “so_test.h”

void test_c()

{

printf(“this is in test_c…/n”);

}

将这几个文件编译成一个动态库:libtest.so

$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

2、动态库的链接

在1、中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。程序的源文件为:test.c。

test.c:

#include “so_test.h”

int main()

{

test_a();

test_b();

test_c();

return 0;

}

l 将test.c与动态库libtest.so链接生成执行文件test:

$ gcc test.c -L. -ltest -o test

l 测试是否动态连接,如果列出libtest.so,那么应该是连接正常了

$ ldd test

l 执行test,可以看到它是如何调用动态库中的函数的。

3、编译参数解析

最主要的是GCC命令行的一个选项:

-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

l -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

l -L.:表示要连接的库在当前目录中

l -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称

l LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

l 当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /in/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。

4、注意

调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。

-lxx

xx是你的.so文件名

其实使用方法和你使用数学库函数是一样的,

源代码

中添加

#include ,编译的时候,加上-lm参数。

注:linux下的扰裤.so文件为共享库,相当于windows下的dll文件。

扩展资料: 

linux下编写调用so文件实例

.so是Linux(Unix)下的

动态链接库

. 和.dll类似. 

比如:

文件有: a.c, b.c, c.c 

gcc -c a.c 

gcc -c b.c 

gcc -c c.c 

gcc -shared libXXX.so a.o b.o c.o 

要使用的话也缓友简很简单. 比如编译d.c, 使用到libXXX.so中的函数, libXXX.so地址是MYPATH 

gcc d.c -o d -LMYPATH -lXXX 

注意不是-llibXXX

test.c文件和一个test.h,这两个文件要生成libsotest.so文件。然后我还有一个testso.c文件,在这个文件里面调用libsotest.so中的函数。

编写的过程中,首先是编告孝译so文件,我没有编写makefile文件,而是参考的2里面说的直接写的gcc命令。

因为so文件里面没有

main函数

,所以是不可执行的,所以编译的时候要加上-c,只生成目标文件。

linux下的.so文件为共享库,相当于windows下的dll文件,使用方法如下:

在你的工程源代码里包含.h头文件,坦颂宽然后可以调用动态库里的函数,在链接的时候加上如下编译器参数:

-l xx.so

如果你的so文件是以lib开樱好头的,还可以直接这样使用:

-lxx

xx是你的.so文件名

其实使用方法和你使用数学库函数是一样的,源代码中添加

#include ,编译让亮的时候,加上-lm参数。

动态链接库,调用,写c语言时用的。放在编译的文件夹里面。包含进去.h就行了、、、、、、、、

安神旅装个开发工具 然脊老后编译就行了 redhat在安装的时候选择自定义就可以安装开发工具 make 然后樱瞎升make install

linux c文件编译so的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux c文件编译so,Linux下C文件如何编译为SO文件?,请问我有一个.so文件,如何在Linux下编程使用呢?的信息别忘了在本站进行查找喔。


数据运维技术 » Linux下C文件如何编译为SO文件? (linux c文件编译so)