C++---初识《通过g++ / makefile 编译和调用动态库so文件》(ubuntu)

时间:2022-09-21 14:38:47

C++---初识《通过g++ / makefile  编译和调用动态库so文件》(ubuntu)

------------------------目录-----------------------------

一、通过makefile  编译和调用动态库so文件

二、通过makefile  编译和调用动态库so文件

-------------------------正文----------------------------

一、通过makefile  编译和调用动态库so文件

1、动态库的编译
  举例,这里有一个头文件:test.h,三个.c文件:test_a.c、test_b.c、test_c.c,这几个文件编译成一个动态库:libtest.so。

C++---初识《通过g++ / makefile  编译和调用动态库so文件》(ubuntu)

文件test.h:

#include   "stdio.h"
void test_a();
void test_b();
void test_c();
文件test_a.c:

#include "test.h"
void test_a()
{
  printf("this is in test_a...\n");
}
文件test_b.c:

#include "test.h"
void test_b()
{
  printf("this is in test_b...\n");
}
文件test_c.c:

#include "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 "test.h"

int main()
{
  test_a();
  test_b();
  test_c();
  return ;
}

将test.c与动态库libtest.so链接生成执行文件test:
 $   gcc test.c -L. -ltest -o test

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

执行:
 $  ./test        #可以看到它是如何调用动态库中的函数的。

遇到问题:
u@u1604:~/C_learn/makefile_so$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so
u@u1604:~/C_learn/makefile_so$ gcc test.c -L. -ltest -o test
u@u1604:~/C_learn/makefile_so$ ldd test
linux-vdso.so. => (0x00007ffc096bf000)
libtest.so => not found
libc.so. => /lib/x86_64-linux-gnu/libc.so. (0x00007f2e43587000)
/lib64/ld-linux-x86-.so. (0x00007f2e43951000) 解决方式一:
u@u1604:~/C_learn/makefile_so$ sudo cp libtest.so /lib # libtest.so复制到/usr/lib下 # 删除命令 : sudo rm /lib/libtest.so
[sudo] u 的密码:
u@u1604:~/C_learn/makefile_so$ gcc test.c -L. -ltest -o test
u@u1604:~/C_learn/makefile_so$ ldd test
    linux-vdso.so.1 =>  (0x00007ffd96947000)
    libtest.so => /lib/libtest.so (0x00007f07a2820000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f07a2456000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f07a2a22000) 成功:
u@u1604:~/C_learn/makefile_so$ ./test
this is in test_a...
this is in test_b...
this is in test_c..

C++---初识《通过g++ / makefile  编译和调用动态库so文件》(ubuntu)

二、通过makefile  编译和调用动态库so文件

C++---初识《通过g++ / makefile  编译和调用动态库so文件》(ubuntu)

文件../hello/hello.c

#include "hello.h"

void hello()
{
printf("Hello .....\n");
}
文件../hello/hello.h

#ifndef _HEAD_H
#define _HEAD_H
#include <stdio.h> void hello(); #endif
文件../hello/Makefile

CC = gcc

OBJS = $(wildcard *.c)

TARGET = libhello.so

all:
  $(CC) $(OBJS) -fPIC -shared -o $(TARGET)
  sudo mv ./$(TARGET) /lib
clean:
  rm $(SRCS) $(headfile)
【解释】主要命令: gcc -hello.c -fPIC -shared -o libhello.so,
这里生成的libhello.so并不是在系统 /lib目录下的,所以将.so文件移动到系统/lib里去
文件 test.c

#include "test.h"

#include <sys/types.h>
#include <sys/wait.h> int main()
{
hello();
return ; }
文件 test.h

#ifndef _HEAD_H
#define _HEAD_H
#include <stdio.h> #endif
文件 makefile

CC = gcc

OBJS = $(wildcard *.c)

TARGET = test

all:
cd ./hello; make
$(CC) $(OBJS) -L/lib -lhello -o $(TARGET) clean:
rm -rf *o $(TARGET)
cd ./hello; make clean 【解释】注意这里的makefile,既make此目录下的,还要进去子目录hello里去make,
所以首先进去子目录cd ./hello;make,然后要连接libhello.so,
主要是 gcc test.c -L/lib -lhello -o test,记得要清除.o 和.so文件
结果
u@u1604:~/C_learn/makefile_so$ make
cd ./hello; make
make[]: Entering directory '/home/u/C_learn/makefile_so/hello'
gcc hello.c -fPIC -shared -o libhello.so
sudo mv ./libhello.so /lib
[sudo] u 的密码:
make[]: Leaving directory '/home/u/C_learn/makefile_so/hello'
gcc test.c -L/lib -lhello -o test
test.c: In function ‘main’:
test.c::: warning: implicit declaration of function ‘hello’ [-Wimplicit-function-declaration]
hello();
^
u@u1604:~/C_learn/makefile_so$ ./test
Hello .....

问题:

如果在打印出现的信息中,发现有一行: libtest.so => not found
则表明链接程序找不到我们的libtest.so文件哦,为什么呢?因为链接程序只寻找固定目录,例如/lib目录。
如果我们的当前目录是诸如/home/u/a/b/c这种目录,那么人家是不会主动了解到的。

怎么办?办法一:把libtest.so拷贝到链接程序的搜索路径目录下。
办法二:设置环境变量LD_LIBRARY_PATH,增加当前路径到该变量中。

看看现在LD_LIBRARY_PATH有什么内容吧?
、执行 echo $LD_LIBRARY_PATH 就打印出来。
、配置环境变量的方法简单点就是:
LD_LIBRARY_PATH=LD_LIBRARY_PATH:"/root/nana/so"
export LD_LIBRARY_PATH
、好了,再次执行ldd就有新发现了。
、执行./***, OK,输出正常。

  " 办法二:设置环境变量LD_LIBRARY_PATH,增加当前路径到该变量中。 "尝试设置环境路径了,可能没对,几经折腾还没编译通过。回头编译通过,再来记录。

  今天收获了,g++  ---->   makefile  ----->  cmake  linux下学习C++编译的三层境界的思维,前者是后者思维的基础,后者是前者进一步提升编程效率的优化。学会三者,是在linux下学习c++必会的技能,后面再学习如何写makelist.txt。

C++---初识《通过g++ / makefile 编译和调用动态库so文件》(ubuntu)的更多相关文章

  1. &lbrack;转&rsqb;linux 调用动态库so文件

    记录一个面试被问到的问题. extern 有什么用途? 除了多文件共享全局变量外还有呢? extern "C" 的功能? 我想看完这篇文章就可以知道第三个问题了. 关于动态调用动态 ...

  2. Makefile中怎样调用python和perl文件为自己提供须要的数据

    Makefile中怎样调用python和perl文件为自己提供须要的数据,利用print函数对外输出数据 实例代码例如以下 perl.pl #!/usr/bin/perl print("he ...

  3. gcc编译工具生成动态库和静态库之一----介绍

     1.库的分类 根据链接时期的不同,库又有静态库和动态库之分. 静态库是在链接阶段被链接的(好像是废话,但事实就是这样),所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行. ...

  4. 修改OpenSSL默认编译出的动态库文件名称

    在 Windows 平台上调用动态链接库 dll 文件时,有两种方式:a) 隐式的加载时链接:使用 *.lib (导入库)文件,在 IDE 的链接器相关设置中加入导入库 lib 文件的名称,或在程序中 ...

  5. Android NDK开发及调用标准linux动态库&period;so文件

    源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...

  6. &num; 2017-2018-2 20155228 《信息安全系统设计原理》 使用VirtualStudio2008创建和调用静态库和使用VirtualC&plus;&plus;6&period;0创建和调用动态库

    使用virtual c++ 6.0创建和调用动态库 不得不说一下关于环境的问题 只要我打一个响指,一半的安装在win7上的VC6.0都会因为兼容性问题直接崩掉 懒得研究怎么解决兼容性的问题了,直接开一 ...

  7. Qt生成和调用动态库dll,和静态库&period;a(windows和linux通用)

    系统1:ThinkPad T570.Windows10.QT5.12.2(Qt Creater 4.8.2)一.动态库.dll的创建和调用1.在qtcreater中按如下步骤创建动态库,动态库名为my ...

  8. windows 创建和调用 动态库,静态库

    windows创建和调用静态库 // MathFuncsLib.h namespace MathFuncs { class MyMathFuncs { public: // Returns a + b ...

  9. c&plus;&plus;调用动态库失败解决办法

    c++调用动态库失败解决办法 之前写好的程序今天早上过来发现在服务器上出错了,于是就各种查问题,整整一个早上外加下午两个小时都在查这个问题,最终被我找到了问题: 在程序中我发现LoadLibrary( ...

随机推荐

  1. MyEclipse &plus;Flex 整合

         最近想利用red5开发一个流媒体的程序,在网上找了半天没有一个可用的代码,要么是下载需要多少币,要么是没有.纠结了半天,最后决定自检看着文字版本的教程,自己编写一个.         看着一 ...

  2. ora 32021 设置参数时参数值长度超过255处理办法

    alter system set db_file_name_convert='AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA-.' scope=spfi ...

  3. 响应者链 hittest&colon;withEvent&colon; 方法的使用

    关于响应者链部分的基础内容 参考http://www.cnblogs.com/wendingding/p/3795171.html 这里我要说明的是 关于- (UIView *)hitTest:(CG ...

  4. 泛型集合List&lt&semi;T&gt&semi; Dictionary&lt&semi;K&comma;V&gt&semi;

    List<T>类似于ArrayList,ArrayList的升级版. 各种方法:Sort().Max().Min().Sum()…   Dictionary<K,V>类似于Ha ...

  5. 借助bool判断使冒泡排序效率提高

    排序问题是编程中最常见的问题.实际应用中,计算机有接近一半时间是在处理有关数据排列的问题,提高排序的效率有助于更快地解决问题. 先来说说平常一般的冒泡算法,使用两个循环,外循环作为整体排序,每趟循环使 ...

  6. JuiceSSh破解分析

    JuiceSSH是一款免费的远程ssh客户端,感觉是一款挺优秀的软件,里边有一些高级功能需要购买高级版才能使用,这里便对其对高级功能的破解进行分析. 本文仅用于学习交流使用,请尊重作者,勿在网上肆意发 ...

  7. Hibernate中用纯SQL查询,并通过hibernate分页返回List&lt&semi;对象&gt&semi;

    @SuppressWarnings("unchecked") public List<Article> getPageQueryList(final int pageN ...

  8. 2017-04-21周Java学习笔记

    2017-04-21-周Java学习笔记... -------------------------------------- 计算机起源于:战争中的炮弹轨道计算.Unix操作系统是使用C语言编写的操作 ...

  9. Gym 101194D &sol; UVALive 7900 - Ice Cream Tower - &lbrack;二分&plus;贪心&rsqb;&lbrack;2016 EC-Final Problem D&rsqb;

    题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...

  10. 手动实现staticmethod和classmethod装饰器

    首先,staticmethod和classmethod装饰器是通过非数据描述符实现的.用法简单,这里就不细说了. 这里主要分析一下staticmethod和classmethod是如何通过描述符实现的 ...