c语言动态链接库制作使用

    1. Gcc编译
      1. 源文件

目录 testso

Hello.h

#ifndef HELLO_H

#define HELLO_H

void hello(const char * name);

#endif

// #ifndef HELLO_H

// #define HELLO_H

//     void hello(const char *name);

Hello.c

#include <stdio.h>

void hello(const char *name){

    printf("hello %s \n",name);

}

Main.c

#include "hello.h"

int main(){

    hello("everyone");

    return 0;

}

      1. 编译
        1. 错误编译

Gcc -o hello hello.c

wzkj@wzkj-virtual-machine:~/work/testso$ gcc -o hello hello.c

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':

(.text+0x24): undefined reference to `main'

collect2: error: ld returned 1 exit status

原因是hello.c中没有main ,main是程序的主入口

        1. 多文件编译
          1. 编译hello.c

Gcc -c hello.c

wzkj@wzkj-virtual-machine:~/work/testso$ gcc -c hello.c

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello.c  hello.h  hello.o  main.c

可以看到多了个hello.o文件它是目标文件,是.c文件经过编译生成的可以被cpu识别的二进制的代码

Gcc -c  === gcc -compile 编译

          1. 编译main.c

Gcc -c main.c

wzkj@wzkj-virtual-machine:~/work/testso$ gcc -c main.c

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello.c  hello.h  hello.o  main.c  main.o

          1. 制作可执行文件

Gcc main.o hello.c -o hello

wzkj@wzkj-virtual-machine:~/work/testso$ gcc main.o hello.o -o hello

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello  hello.c  hello.h  hello.o  main.c  main.o

wzkj@wzkj-virtual-machine:~/work/testso$ ./hello

hello everyone

      1. 静态链接库
  1. gcc -c hello.c
  2. Ar rcs libmyhello.a hello  生成静态链接库

ar rcs libmyhello.a hello.o

wzkj@wzkj-virtual-machine:~/work/testso$ ar rcs libmyhello.a hello.o

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello.c  hello.h  hello.o  libmyhello.a  main.c

Gcc -o hello main.c -static -L. -lmyhello

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello.c  hello.h  hello.o  main.c

wzkj@wzkj-virtual-machine:~/work/testso$ ar rcs libmyhello.a hello.o

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello.c  hello.h  hello.o  libmyhello.a  main.c

wzkj@wzkj-virtual-machine:~/work/testso$ gcc -o hello main.c -static -L. -lmyhello

wzkj@wzkj-virtual-machine:~/work/testso$ ./hello

hello everyone

wzkj@wzkj-virtual-machine:~/work/testso$

刚才 -L. -lmyhello 少写了个-

静态库制作完了,如何使用它内部的函数呢?只需要在使用到这些公用函数的源程序中包含这些公用函数的原型声明,然后在用gcc命令生成目标文件时指明静态库名,gcc将会从静态库中将公用函数连接到目标文件中。注意,gcc会在静态库名前加上前缀lib,然后追加扩展名.a得到的静态库文件名来查找静态库文件,因此,我们在写需要连接的库时,只写名字就可以,如libmyhello.a的库,只写:-lmyhello

所以生成需要 libmyhello.a  但是使用 -lmyhello 不需要Lib了

      1. 动态链接库(共享链接库)

gcc动态链接库so的制作和使用 - 立志做一个好的程序员 - 博客园

gcc -shared -fPIC -c hello.c(可能没用)

gcc -shared -fPIC -o libmyhello.so hello.o(生成libmyhello.so)

 gcc -o hello main.c -L. -lmyhello  (生成hello)

gcc -shared -fPIC -c hello.c

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello.c  hello.h  hello.o  main.c

wzkj@wzkj-virtual-machine:~/work/testso$ gcc -shared -fPIC -o libmyhello.so hello.o

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello.c  hello.h  hello.o  libmyhello.so  main.c

wzkj@wzkj-virtual-machine:~/work/testso$ gcc -o hello main.c -L. -lmyhello

wzkj@wzkj-virtual-machine:~/work/testso$ ls

hello  hello.c  hello.h  hello.o  libmyhello.so  main.c

wzkj@wzkj-virtual-machine:~/work/testso$ ./hello

./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

wzkj@wzkj-virtual-machine:~/work/testso$ ^C

解决这个libmyhello.so cannot open shared objectfile no such file or directory问题,4种方法

  1. cp libmyhello.so /usr/lib  copy libmyhello.so 到 /usr/lib 下
  2. Sudo ldconfig /home/wzkj/work/testso

如果使用完毕后,不想加载libmyhello.so,把libmyhello.so 挪走,然后再执行下

Sudo ldconfig /home/wzkj/work/testso 即可

  1. 修改/etc/ld.so.conf

再最后增加libmyhello.so 目录

/home/wzkj/work/testso

  1. 在命令行执行

Export  LD_LIBRARY_PATH=/home/wzkj/work/testso

  1. 有时候,还需要sudo ldconf进行加载

ldconfig几个需要注意的地方

1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library会找不到

2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到

比如安装了一个mysql到/usr/local/mysql,mysql有一大堆library在/usr/local/mysql/lib下面,这时 就需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib,保存过后ldconfig一下,新的library才能在 程序运行时被找到。

3. 如果想在这两个目录以外放lib,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变 量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时 候使用。

4. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。

5. 总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。

ldconfig命令 - Linux命令大全 | linux教程  linux命令大全

ldconfig用法_qeshining的博客-CSDN博客

gcc动态链接库so的制作和使用 - 立志做一个好的程序员 - 博客园

      1. Sqlite3安装

Ubuntu编译安装sqlite3库_北极熊~~的博客-CSDN博客_ubuntu安装sqlite

Ubuntu18.04 sqlite3安装及其应用 - 灰信网(软件开发博客聚合)

  1. tar -zxvf sqlite-autoconf-3110000.tar.gz
  2. ./configure  --prefix=/home/wzkj/mysqlite3 (//--prefix用于指定sqlite库文件、头文件和可行性命令的安装路径)
  3. Make   编译  这时间有点长
  4. Sudo make install  这把软件安装到 /home/wzkj/mysqlite3中
  5. mysqlite3中有4个文件夹 bin include lib share
  6. 把include中的文件copy到/usr/include中

Cd mysqlite3/include

Sudo cp * /usr/include

  1. 把lib中copy 到/usr/lib中

cp libsqlite3* /usr/lib/

wzkj@wzkj-virtual-machine:~/mysqlite3/lib$ ls

libsqlite3.a   libsqlite3.so    libsqlite3.so.0.8.6

libsqlite3.la  libsqlite3.so.0  pkgconfig

把所有的libsqlite3都copy走, 不copy pkgconfig

wzkj@wzkj-virtual-machine:~/mysqlite3$ ls

bin  include  lib  share

wzkj@wzkj-virtual-machine:~/mysqlite3$ cd bin/

wzkj@wzkj-virtual-machine:~/mysqlite3/bin$ ls

sqlite3

wzkj@wzkj-virtual-machine:~/mysqlite3/bin$ cd ..

wzkj@wzkj-virtual-machine:~/mysqlite3$ cd include/

wzkj@wzkj-virtual-machine:~/mysqlite3/include$ ls

sqlite3ext.h  sqlite3.h

wzkj@wzkj-virtual-machine:~/mysqlite3/include$ cd ../lib

wzkj@wzkj-virtual-machine:~/mysqlite3/lib$ ls

libsqlite3.a  libsqlite3.la  libsqlite3.so  libsqlite3.so.0  libsqlite3.so.0.8.6  pkgconfig

wzkj@wzkj-virtual-machine:~/mysqlite3/lib$ ls ../share/

man

wzkj@wzkj-virtual-machine:~/mysqlite3/lib$

      1. 制作动态链接库
  1. Wz_sqlite3.c 的编译也需要 -l连接

 gcc -c wz_sqlite3.c -lsqlite3

2)

gcc -o -fPIC wz_sqlite3.c -lsqlite3

gcc -c -fPIC wz_sqlite3.c -lsqlite3

gcc -shared -fPIC -o libwzsqlite3.so  wz_sqlite3.o

gcc -o demo demo.c -lsqlite3 -lwzsqlite3

sudo cp libwzsqlite3.so /usr/lib

wzkj@wzkj-virtual-machine:~/work/wzsqlite$ sudo ldconfig

wzkj@wzkj-virtual-machine:~/work/wzsqlite$ gcc -o demo demo.c -lsqlite3 -lwzsqlite3

      1. 制作总结
  1. c语言在.h中的全局成员变量 是以extern 开头,只声明,不能赋值,但在对应的.c中还需要重新定义

例如以wz_sqlite3.c 中为例

Wz_sqlite.h

Wz_sqlite.c

Extern int open_sqlite_flag;  //不赋值

Extern sqlite3 *db;

Extern sqlite_path ; //不赋值

对应的地方需要重新定义赋值

Int open_sqlite_flag = 0;

Sqlite3 *db = NULL;

Sqlite_path = smart.db;

  1. 编译  

一般的编译

Gcc -c  hello.c; //生成hello.o

但是使用sqlite的

Gcc -c wz_sqlte.c -lsqlite3;//生成wz_sqlite.o  需要使用-l做连接

但是上面使用这个在做进一步的动态连接库会有问题,原因是使用了extern 会有问题,因此

Gcc -c -fPIC wz_sqlite.c -lsqlite3;

  1. 制作 动态连接

Gcc -shared -fPIC -o libwzsqlite3.so wz_sqlite3.o

  1. 复制 libwzsqlite3.so 到 /usr/lib中

Sudo cp libwzsqlite3.so /usr/lib

  1. sudo ldconfig 启用或者增加到动态链接库中,否则使用的时候会报动态链接库找不到
  2. 制作 可执行

Gcc -o demo demo.c -lsqlite3 -lwzsqlite

  1. 执行
  2. 动态链接库都需要放在/usr/lib 中,对应的.h 需要发放到/usr/include中,否则系统找不到
  3. 没有反倒/usr/lib中的 启用动态链接库方式

9.1)修改/etc/ld.so.conf 在最下面添加 动态链接库所在目录即可 然后sudo ldconfig启用

9.2)或者sudo ldconfig /动态链接库目录

9.3)直接在命令行中  Export  LD_LIBRARY_PATH=/home/wzkj/work/testso

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值