2015-01-30 19:58:38 v6543210 阅读数 527

目录

 一、生成 .a

二、生成 .so

三、调用.a

四、调用.so

1.隐式调用

2.显式调用


对于一个dll.cpp内容如下:

定义2个函数。我们只用到了add函数。

  int add(int a,int b){
{
      return a+b;
}}
 
  int subtract(int a,int b)
{
     return a-b;
}

 一、生成 .a

gcc -c dll.cpp
ar -rc libadd.a dll.o

将dll.cpp编译成dll.o

再将dll.o生成libadd.a

二、生成 .so

gcc  -shared -o libadd.so dll.cpp

生成 libadd.so

三、调用.a

main.cpp 内容如下:

#include <stdio.h>
//using namespace std;


 int add(int a,int b);//函数声明一般应放在dll.h中 然后#include <dll.h>
 int subtract(int a,int b);//函数声明同上
 

int main()
{
	 int a=20;
	 int b=10;
	 printf("%d+%d=%d\n",a, b, add(a,b));
	 //cout<<"a + b = "<<add(a,b)<<endl;
	 //cout<<"a - b = "<<subtract(a,b)<<endl;
	 return 0;
}

 

gcc -o main main.cpp  -static  -ladd

这个命令默认是优先使用动态库。加-static强制链接静态库。

 

四、调用.so

1.隐式调用

main.cpp如上所述

gcc -o main main.cpp -ladd

2.显式调用

显示调用是通过系统函数dlopen() 、dlsym(),等直接获取函数指针进行调用。

这里注意dlsym(handle, "_Z3addii")函数中,"_Z3addii"是dll.cpp中add 函数名称被 mangling(名称混淆)后的结果。如果想不被混淆,请加extern "C",如下:

 extern "C"
{
	int add(int a,int b)
	{
      		return a+b;
	}
}
 

main_load.cpp内容如下:

#include <stdio.h>

#include <dlfcn.h>//dlopen所在的头文件


int main()
{
  
        typedef int (*AddProc)(int,int);
		AddProc Add;
		AddProc pt_str;
		//int (*pt_str)(int, int);		
		/*加载库*/
		void *handle = dlopen("./libadd.so", RTLD_LAZY);
		if(!handle)
         {
            printf("dlopen error!\n");
            return 1;
         }
		pt_str = (AddProc) dlsym(handle, "_Z3addii");
		 if(!pt_str)
         {
            printf("动态连接库库函数未找到\n");
            return 1;
         }

		 
         int a=20;
         int b=10;
         printf("%d+%d=%d\n",a, b, pt_str(a,b));;
		/*卸载库*/
		dlclose(handle);
        return 0;
}

编译命令:

gcc -o main_load main_load.cpp  -ldl

记得把系统库libdl.so带上。
 

 

 

2018-07-11 11:28:38 Lasuerte 阅读数 387

原贴地址https://blog.csdn.net/guowenyan001/article/details/50353214

一、代码

1.1 说明

        hello.h、hello.c是生成库的代码。

        main.c是调用库的代码。

1.2 代码

hello.h:

  1. #ifndef HELLO_H
  2. #define HELLO_H
  3. void hello(const char* name);
  4. #endif

hello.c:

  1. #include <stdio.h>
  2. #include "hello.h"
  3. void hello(const char* name)
  4. {
  5. printf("Hello %s\n", name);
  6. }

main.c:

  1. #include "hello.h"
  2. int main()
  3. {
  4. hello("everyone!");
  5. return 0;
  6. }

二、生成、调用静态库(.a)

2.1 生成静态库

生成hello.o:

        gcc -c hello.c

生成静态库libmyhello.a:

        ar cr libmyhello.a hello.o

2.2 调用静态库

使用静态库编译程序

        gcc -o hello main.c -L. -lmyhello

执行程序

        ./hello 

三、生成、调用动态库(.so)

3.1 生成动态库

生成hello.o:

        gcc -c -fPIC hello.c

生成动态库libmyhello.so:

        gcc -shared -fPIC -o libmyhello.so hello.o

3.2 调用动态库

使用动态库编译程序 

       gcc -o hello main.c -L. -lmyhello

将动态库到/usr/lib64目录

        动态库默认到/usr/lib64目录下查找

        mv libmyhello.so /usr/lib64

执行程序

        ./hello 

3.3 运行结果



参考资料:

        在Linux中创建静态库.a和动态库.so:http://www.cnblogs.com/laojie4321/archive/2012/03/28/2421056.html

2016-09-28 10:10:22 Clovelegent 阅读数 380

动态库共享库

第一步:通过gcc -fPIC -c 编译生成.o文件

gcc -fPIC -c a.c   (编译生成.o文件 -fPIC与位置无关)

gcc -fPIC -c b.c

生成a.o,b.o编译文件。


第二步:通过上面已经生成的a.o,b.o文件生成.so文件
方法1: gcc -shared -Wl -o liba.so a.o
方法2: gcc -shared -Wl,-soname,libab.so.1 -o libab.so.1.10 a.o b.o

第三步:通过依赖库编译生成可执行文件
main.c 引用已经生成的.so文件 libmyab.so.1.10
编译方法:gcc main.c libmyab.so.1.10 -o app
编译生成 app 
运行 $ ./app
出错:error while loading shared libraries: libcalc.so.1: cannot open shared object file: No such file or directory
ldd察看依赖库:
$ ldd app
linux-gate.so.1 =>  (0xb77c8000)
libcalc.so.1 => not found    <============注意
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb760c000)
/lib/ld-linux.so.2 (0xb77c9000)
注意点libcalc.so.1 => not found动态库没有找到
解决方法:把动态库路径添加到配置文件中:$ sudo vi /etc/ld.so.conf
更新动态库:$ sudo ldconfig -v
重新运行./app成功

生成so name : -Wl,-soname,libxxx.so.1
生成link name : ln -s libxxx.so.1.10 xxx.so


静态库
gcc -c -fPIC *.c
ar rcs libxx.a *.o

nm :察看文件包含内容
$ nm libcalc.a 

add.o:
00000000 T add

dive.o:
00000000 T dive

mul.o:
00000000 T mul

sub.o:
00000000 T sub

编译:
$ gcc main.c lib/libcalc.a -o app

静态库和共享库的区别:
静态库优点:app随便放哪都可以运行
缺点:lib合入app导致app体积变大


2016-07-18 14:59:26 u012592062 阅读数 2720

Linux库文件.a .so

1.

.o 就相当于windows里的obj文件 ,一个.c或.cpp文件对应一个.o文件
.a 是好多个.o合在一起,用于静态连接 ,即STATIC mode,多个.a可以链接生成一个exe的可执行文件
.so 是shared object,用于动态连接的,和windows的dll差不多,使用时才载入。


得到了ts:error while loading shared libraries: libs.so: cannot open shared object file: No such file or directory 系统不能找到我们自己定义的libs.so,那么告诉他,修改变量LD_LIBRARY_PATH。

 

2. 怎么生成so动态库文件?

编译:得到输出文件libs.o 
gcc -fPIC -g -c s.c -o libs.o 
  
链接:得到输出文件libs.so 
gcc -g -shared -Wl,-soname,libs.so -o libs.so libs.o -lc

得到了ts:error while loading shared libraries: libs.so: cannot open shared object file: No such file or directory 系统不能找到我们自己定义的libs.so,那么告诉他,修改变量LD_LIBRARY_PATH。

 

3. 怎么生成a静态库文件?

编译:得到输出文件libs.o 
gcc -fPIC -g -c s.c -o libs.o 
ar r .a .o

 

4.

看.a结构,找其中的原文件,用ar -t YourFile.a

看动态库用 nm -d lib*.so


test.h

复制代码
1 #ifndef _TEST_H_
2 #define _TEST_H_
3
4 void TestA();
5 void TestB();
6
7 #endif
复制代码



test_a.cpp

复制代码
1 #include <stdio.h>
2 #include "test.h"
3
4 void TestA()
5 {
6 printf("TestA func\n");
7 }
复制代码



test_b.cpp

复制代码
1 #include <stdio.h>
2 #include "test.h"
3
4 void TestB()
5 {
6 printf("TestB func\n");
7 }
复制代码



生成so文件的命令

g++ test_a.cpp test_b.cpp -fPIC -shared -o libtest.so

生成.a文件的命令

1 gcc -c test_a.cpp
2 gcc -c test_b.cpp
3 ar -r libtest.a test_a.o test_b.o




test.cpp

复制代码
1 #include "test.h"
2
3 int main()
4 {
5 TestA();
6 TestB();
7
8 return 0;
9 }
复制代码



采用动态库编译命令

g++ test.cpp -o test -L. -ltest



执行

export LD_LIBRARY_PATH=./
./test

执行结果如下。

 

采用静态库编译命令

g++ -static -o test -L. -ltest test.cpp

执行效果


静态库的嵌套调用,有时候我想做一个自己的静态库,它里面要调用其他静态库里面的函数,经过试验

这个好像用ar -r不行,所以就在链接的时候需要两个库文件都包含,同时要有这一个头文件才行。。。


2019-12-21 10:15:03 qq1773304209 阅读数 20

动态链接

简单理解就是可执行文件记录库的路径,通过路径找到对应库文件,库文件删除,执行文件不可执行
优点:不占空间

缺点:效率低

linux生成.so文件

    gcc -fPIC -shared test.c -o libtest.so


    -fPIC		是压制警告 
    -shared		是生成动态库 
    test.c		是要编译成库的文件
    -o后面	   是要生成的文件的名称(lib+name)

linux使用.so文件

gcc -g -o main main.c -ltest -L.

-L.    -L后加动态库路径(.代表本地目录)、
-l		后面加库名称(name)		

执行文件前会报错“cannot open shared object file: No such file or directory”,执行下面命令把.so库文件的路径写入LD_LIBRARY_PATH

export LD_LIBRARY_PATH=库文件绝对路径:$LD_LIBRARY_PATH

静态链接

可以理解成可执行文件中包含了库代码的一份完整拷贝,之后库文件删除了也能使用

优点:效率高

缺点:占空间

linux生成.a文件

1.编译成.o文件
	gcc -c -o test.o test.c 
2.ar工具把.o文件打包成.a
	ar -r -s -o libtest.a test.o
		-s:ranlib

linux使用.so文件

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

-L.    -L后加静态库路径(.代表本地目录)、
-l		后面加库名称(name)	
没有更多推荐了,返回首页