linux环境下完成 含有opecv 的动态链接库调用

最近在研究linux环境下完成动态链接库的调用,为后面的项目做准备,因为要做图像方面的处理,所以直接来一个包含opencv的动态链接库调用。

概念的东西后面在解释,直接开搞:

1、新建Function.cpp作为动态链接库,内容如下:

#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;

int F_sum(int a,int b)
{
  int c=a+b;
  printf("this sum is: %d\n",c);
  return 0;
}

 int S_F(int flag,Mat ImageMat)
 {
   
   namedWindow("ImageWindow");
   switch(flag)
   {
   case 0:
   printf("this is a false\n");
   break;
   case 1:
   imshow("ImageWindow",ImageMat);
   break;  
   }
   return 0;
 }

2、新建Function.h作为头文件,内容如下:

#include <opencv2/opencv.hpp>
using namespace cv;

int F_sum(int a,int b);
int S_F(int flag,Mat ImageMat);

3、新建main.cpp作为主函数,用于链接库的调用测试,内容如下:

#include <opencv2/opencv.hpp>
#include "Function.h"

using namespace cv;
using namespace std;

int main()
 {
  Mat ImageMat=imread("1.jpg");
  //imshow("image",ImageMat);
  F_sum(8,8);
  S_F(1,ImageMat);
  waitKey();
  return 0;
 }

 

4、编译生成动态链接库:

    将Function.cpp  Function.h  放到linux某文件夹下

在该目录下,执行下列指令:

g++ -c -fPIC Function.cpp -o Function.o

g++ -shared Function.o -o libFunction.so    

此时在该文件夹下就生成了,Function.o 和libFunction.so 两个文件,其中libFunction.so就是所谓的动态链接库。

注意:动态链接库的命名前面一定要加lib!

5、将libFunction.so  、Function.h、 main.cpp 放到同一目录下,执行下列指令:

g++ -c main.cpp -o main.o

g++ main.o -o  main.exe `pkg-config --cflags --libs opencv` -L. -lFunction

export LD_LIBRARY_PATH=.

注意:1、链接的时候,要加上`pkg-config --cflags --libs opencv`,  可以连接到opencv库。

            2、 -L. -lFunction,此语句是连接本地文件夹中的libFunction.so ,也就是上一步生成的。

6、执行  ./main.exe 测试程序效果,收工!

 

 

概念一:一个C++源代码要最终变成一个可执行文件需要经过四个步骤:

1、预处理(pro-processing)

2、编译(compiling)

3、汇编(assembling)

4、链接(link)

新建一个test.cpp,其变化过程如下:

test.cpp---(预处理)---test.i---(编译)---test.s---(汇编)---test.o---(链接)---test.exe

 

概念二: 相关关键字的解释

-o 选项表示将源代码预处理后输出在指定文件中

-E 选项使用g++/gcc将源代码预处理后不执行其他动作(预处理)

-S 选项使用g++/gcc将预处理后的文件编译,翻译成汇编代码(编译)

-c 选项将编译生成的test.s文件生成二进制目标代码(汇编)

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

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

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

概念三:linux中的.so文件是共享文件,跟windows下的.dll类似。

gcc和g++分别是GNU(一个开源组织)的c&c++编译器

对于.c后缀的文件,gcc把它当做是C程序,g++当做是C++程序;对于.cpp后缀的文件,gcc和g++都会当做c++程序。

gcc可以根据后缀名为.c或.cpp分别按c程序和c++程序来编译,但是g++无论是.c或.cpp都统一按c++程序来编译。

 

 

概念四:静态库和动态库对比

二者的不同点在于代码被载入的时刻不同。

静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。

静态用.a为后缀, 例如: libhello.a

共享库(动态库)的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。

动态通常用.so为后缀, 例如:libhello.so

共享库(动态库)的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。
 

概念五:pkg-config工具

g++编译c++程序时,需要用-L和-I来分别制定连接库和头文件信息,但是opencv库文件和头文件繁多,不可能每次编译都写上一堆连接信息,而且不同人可能会安装在不同路径,查找也困难,于是需要使用pkg-config工具来自动找出依赖库和头文件信息,仅需输入pkg-config–libs –cflags opencv, 

当安装一个库时(例如从RPM,deb或其他二进制包管理系统),会包括一个后缀名为pc的文件,在这个.pc文件里包含有数个条目。

可以在linux中打开opencv.pc看一下其内容,路径:/usr/local/lib/pkgconfig/opencv.pc

内容如下:

ls@Precision-Tower-5810:/usr/local/lib/pkgconfig$ cat opencv.pc
# Package Information for pkg-config

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 3.4.1
Libs: -L${exec_prefix}/lib -lopencv_ml -lopencv_superres -lopencv_cudacodec -lopencv_stitching -lopencv_cudastereo -lopencv_cudafeatures2d -lopencv_videostab -lopencv_cudaoptflow -lopencv_photo -lopencv_cudaobjdetect -lopencv_cudalegacy -lopencv_calib3d -lopencv_features2d -lopencv_highgui -lopencv_cudawarping -lopencv_cudaimgproc -lopencv_objdetect -lopencv_flann -lopencv_cudafilters -lopencv_cudaarithm -lopencv_cudabgsegm -lopencv_videoio -lopencv_imgcodecs -lopencv_shape -lopencv_video -lopencv_dnn -lopencv_imgproc -lopencv_core -lopencv_cudev
Libs.private: -ldl -lm -lpthread -lrt -lcudart -lnppc -lnppial -lnppicc -lnppicom -lnppidei -lnppif -lnppig -lnppim -lnppist -lnppisu -lnppitc -lnpps -lcublas -lcufft -L-L/usr/local/cuda -llib64
Cflags: -I${includedir_old} -I${includedir_new}
luzaiwang@jdh-Precision-Tower-5810:/usr/local/lib/pkgconfig$

可以看到内容里面。包含用于其他使用这个库的程序编译时需要的库设置,以及头文件的位置,版本信息和简介等等

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值