Linux的动态库文件是以lib字样开头的.so文件,编译链接动态库有两个要点:一个是需要用-L选项指定动态库的搜索路径,这个搜索路径是需要连接的so文件的大致路径,比如/usr/openssl/lib;另外还需要用-l(这个是小写的L)选项指定动态库的名字,比如下面这条编译命令:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
Ⅱ Linux上怎么用GCC编译动态库
以创建文件hello.c,内容如下:
#include
voidhello(void)
{
printf("HelloWorld ");
}
用命令
gcc-sharedhello.c-olibhello.so
编译为动态库。可以看到,当前目录下多了一个文件libhello.so。
Ⅲ linux怎样实现c语言动态库与静态库的链接
Linux系统中静态库是.a文件,编译链接.a文件只需要加上.a文件的完整的文件路径就可以了,比如:
gcc
-o
hello
hello.c
/usr/lib/libm.a
Linux系统的动态库是系统中的.so文件,编译链接动态库需要用-L参数指定动态库的搜索路径,还要用-l(这个是小写的L)指定动态库的名字,比如:
gcc
-o
hello
hello.c
-L/usr/openssl/lib
-lcrypto
Ⅳ LLINUX GCC 编译C使用自定义动态链接库.so的问题
1. 可以参考如下关于库文件的文章:http://numanal.com/?p=129
2. 在编译文件时最好用-L指明自定义库的存在目录, 利用如下任一语句(.so文件与.c文件在同一目录):
gcc test.c -o test2 -L./verify.so
gcc test.c -o test2 -L.
3. 你这里在的问题应该与编译器的某些兼容性有关, 在实际编写程序的时候最好按gcc的语法规范走, 避免不必要的错误.
Ⅳ linux动态库编译
Linux动态库的编译与使用 转载
http://hi..com/linuxlife/blog/item/0d3e302ae2384d3a5343c1b1.html
Linux下的动态库以.so为后缀,我也是初次在Linux下使用动态库,写一点入门步骤,以便以后能方便使用。
第一步:编写Linux程序库
文件1.动态库接口文件
//动态库接口文件getmaxlen.h
#ifndef _GETMAXLEN_H_
#define _GETMAXLEN_H_
int getMaxLen(int *sel,int N);
#endif
文件2.动态库程序实现文件
//动态库程序实现文件getmaxlen.c
#include "getmaxlen.h"
int getMaxLen(int *sel,int N)
{
int n1=1,n2=1;
for(int i=1;i<N;i++)
{
if(sel[i]>sel[i-1])
{
n2 ++;
if(n2 > n1)
{
n1 = n2;
}
}
else
{
n2 = 1;
}
}
return n1;
}
第二步:编译生成动态库
gcc getmaxlen.c –fPIC –shared –o libtest.so
由以上命令生成动态库libtest.so,为了不需要动态加载动态库,在命令时需以lib开头以.so为后缀。
–fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
–shared:指明编译成动态库。
第三步:使用动态库
1. 编译时使用动态库
文件1.动态库使用文件test.c
//使用动态库libtest.so,该文件名为test.c
#include "getmaxlen.h"
int main()
{
int Sel[] = {2,3,6,5,3,2,1,2,3,4,5,6,7,6,5};
int m;
m = getMaxLen(Sel,15);
printf("%d",m);
return 0;
}
编译命令:
gcc test.c –L . –l test –o test
–L:指明动态库所在的目录
-l:指明动态库的名称,该名称是处在头lib和后缀.so中的名称,如上动态库libtest.so的l参数为-l test。
测试:
ldd test
ldd 测试可执行文件所使用的动态库
2. 动态加载方式使用动态库
文件内容:
//动态库的动态加载使用
int main()
{
void *handle = NULL;
int (*getMaxLen)(int *sel,int N);
int sel[] = {1,2,5,4,5,8,6,5,9,5,4,5,4,1};
handle = dlopen("./libtest.so",RTLD_LAZY);
if(handle == NULL)
{
printf("dll loading error.\n");
return 0;
}
getMaxLen = (int(*)(int *,int))dlsym(handle,"getMaxLen");
if(dlerror()!=NULL)
{
printf("fun load error.\n");
return 0;
}
printf("%d\n",getMaxLen(sel,15));
}
编译命令:
gcc –ldl test1.c –o test
gcc -o test test.c ./libmytools.so
Ⅵ Linux下的静态库和动态库
静态库
可以把它想象成是一些代码的集合,在可执行程序运行前就已经加到了代码中,成为了执行程序的一部分,一般是以.a为后缀的文件名,Windows下后缀为.lib。静态库的命名也分为三部分,1、前缀:lib,2、库的名称:随意,如lisi,3、后缀:.a。
静态库优缺点
上面简单介绍了静态库,那它自然也会有优缺点,这里来介绍下它的优缺点。
优点:1、在最后,函数库是被打包到应用程序中的,实现函数本地化、寻址方便、高效。2、程序在运行的时候,与函数库没有关系,移植性更强。
缺点:1、消耗资源较大,每个进程在使用静态库的时候,都要复制一份才可以,这也就造成了内存的消耗。2、在程序更新、部署、发布的时候,使用静态库相对麻烦,如果一个静态库更新了,那它的应用程序都需要重新编译,再发送给用户,有的时候可能只是一个小的改动,但对于用户来说,会导致整个程序重新下载。
动态库
在程序编译时不会被连接到目标代码中,在后期运行时才会载入,不同的应用程序如果调用相同的库,内存中只有一份共享库的拷贝,也就避免了空间的浪费问题。一般以.so作为文件后缀名,也分为三部分:1、前缀:lib,2、库名称:自定义,3、后缀:.so
动态库优缺点
优点:1、节省内存2、部署、升级相对方便,只需要更换动态库,再重新启动服务即可。
缺点:1、加载速度比静态库慢2、移植性较差,需要把所有用到的动态库进行移植。
Ⅶ linux下 如何用NDK生成C语言动态库
先将要编译的源代码文件移动到一个目录下面,写好makefile文件,一般是已经写好的(没有的话就要自己写了),然后配置好ndk环境变量,在/etc/profile目录下添加export NDK_ROOT=/你的nkd路径,然后保存,重启机器,最后就是cd到你要编译的源码目录下,调用ndk_build就行了
Ⅷ linux 静态库和动态库编译的区别
Linux库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。例如:libhello.so libhello.a
为了在同一系统中使用不同版本的库,可以在库文件名后加上版本号为后缀,例如: libhello.so.1.0,由于程序连接默认以.so为文件后缀名。所以为了使用这些库,通常使用建立符号连接的方式。
ln -s libhello.so.1.0 libhello.so.1
ln -s libhello.so.1 libhello.so
动态库和静态库的区别:
当要使用静态的程序库时,连接器会找出程序所需的函数,然后将它们拷贝到执行文件,由于这种拷贝是完整的,所以一旦连接成功,静态程序库也就不再需要了。然而,对动态库而言,就不是这样。动态库会在执行程序内留下一个标记‘指明当程序执行时,首先必须载入这个库。由于动态库节省空间,linux下进行连接的缺省操作是首先连接动态库,也就是说,如果同时存在静态和动态库,不特别指定的话,将与动态库相连接。
两种库的编译产生方法:
第一步要把源代码编绎成目标代码。以下面的代码hello.c为例,生成hello库:
/* hello.c */
#include
void sayhello()
{
printf("hello,world\n");
}
用gcc编绎该文件,在编绎时可以使用任何全法的编绎参数,例如-g加入调试代码等:
gcc -c hello.c -o hello.o
1.连接成静态库
连接成静态库使用ar命令,其实ar是archive的意思
$ar cqs libhello.a hello.o
2.连接成动态库
生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:
$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o
另外再建立两个符号连接:
$ln -s libhello.so.1.0 libhello.so.1
$ln -s libhello.so.1 libhello.so
这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序。
-Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。实际上,每一个库都有一个soname,当连接器发现它正在查找的程序库中有这样一个名称,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运行的实际文件名,在程序执行期间,程序会查找拥有 soname名字的文件,%B
Ⅸ Linux下C/C++动态库在运行时是怎样加载进来的
在linux上,你在ps中说的那种"将动态库作为一个参数传到程序里"的使用方式,是通过dlopen函数将.so加载到当前进程中,并且通过ld.so将.so"链接"进当前进程。这个"链接"过程包括:查找未定义符号在当前进程中的地址、分配数据/代码/bss段内存(数据初始化全局变量、代码段重定位)、执行constructor函数等。之后,可以使用dlsym在已知符号名的情况下通过符号名查找符号对应的地址。这个符号可以是一个全局变量、全局函数等。在你说的C++中,重载的函数也可以理解为全局函数,会有一个属性为weak的符号。该符号的符号名如果不做修改,默认按照System V的C++ API命名规范命名(以保证linux下不同编译器编译出来的.so和.o可以通用)。但如果使用extern "C"修饰之后,变成C的函数名,则无名称修饰,便于使用。
它怎样实例化我实现的继承类?
实例化的方式和正常链接一样。例如你在之类Derived中重载了基类Base中函数virtual void foo();那么你需要在你的.so中导出一个可以new Derived()的函数,并且返回结果为Base *,这样别人可以在没有Derived定义的情况下获得运行时类型为Derived的对象。此时别人虽然只有Base *的类型,但是仍然可以和正常链接一样通过虚表查virtual void foo()的地址,从而调用你定义的foo()。
此外,如果你定义了继承类的全局变量,在加载.so的时候该全局变量会自动初始化,你也可以将这个初始化的类通过指向Base *的指针传出去。
如果有大神能解释一下windows下动态库和静态库的原理,小弟感激不尽!
和Linux差不多,不过在实现细节上有些出入。例如windows链接时要直接链接.dll需要通过链接生成这个.dll时生成的.lib,而Linux上直接链接.so即可。不过运行时链接无需这个.lib。静态库都是目标文件的压缩包。都是ELF格式。至于共享内存之类的,仅仅取决于section的属性。
Ⅹ linux中编译时怎么连接动态库
Linux系统中静态库是.a文件,编译链接.a文件只需要加上.a文件的完整路径就可以了,比如:
gcc -o hello hello.c /usr/lib/libm.a
Linux系统的动态库是.so文件,编译链接动态库需要用-L参数指定动态库的搜索路径,还要用-l(这个是小写的L)指定动态库的名字,比如:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto