OPENCV静态编译与动态编译
- 格式:pdf
- 大小:372.92 KB
- 文档页数:7
静态库和动态库编译静态库和动态库是编程中常用的两种库文件形式,本文将介绍它们的编译过程和使用方法。
1. 静态库编译静态库是一种在编译时被链接到程序中的库文件,它包含了程序所依赖的所有函数和数据结构,因此程序在运行时不需要再加载库文件。
静态库的编译过程包括以下步骤:(1)创建一个或多个源文件,使用编译器将它们编译成目标文件(.o 或 .obj)。
(2)将多个目标文件打包成一个静态库文件,通常使用 ar 工具完成此操作。
例如,在 Linux 系统下,可以使用以下命令创建名为 libfoo.a 的静态库文件:$ ar rcs libfoo.a foo1.o foo2.o ...其中,rcs 参数分别表示创建、向库文件中添加目标文件和生成索引表。
(3)在编译器中使用静态库,需要将其链接到目标程序中。
在Linux 系统下,可以使用以下命令编译名为 main.c 的源文件和名为libfoo.a 的静态库文件:$ gcc -o main main.c -L. -lfoo其中,-L 参数指定库文件搜索路径,. 表示当前目录;-l 参数指定链接库文件,实际上是将其前缀 lib 和后缀 .a 去掉,即 foo。
2. 动态库编译动态库是一种在程序运行时动态加载的库文件,它只包含程序所需要的部分函数和数据结构,因此可以减小程序的尺寸和加载时间。
动态库的编译过程包括以下步骤:(1)创建一个或多个源文件,使用编译器将它们编译成目标文件。
(2)将多个目标文件打包成一个共享库文件,通常使用 ld 或链接器完成此操作。
例如,在 Linux 系统下,可以使用以下命令创建名为 libfoo.so 的动态库文件:$ gcc -shared -o libfoo.so foo1.o foo2.o ...其中,-shared 参数表示生成共享库文件。
(3)在编译器中使用动态库,需要将其链接到目标程序中。
在Linux 系统下,可以使用以下命令编译名为 main.c 的源文件和名为libfoo.so 的动态库文件:$ gcc -o main main.c -L. -lfoo其中,-L 和 -l 参数的含义同静态库。
C语言中的静态分析与动态分析技巧在C语言编程中,静态分析和动态分析是两种常用的技巧,用于检测程序中潜在的问题和优化程序性能。
静态分析是在编译时进行分析的过程,主要用来检测代码中的潜在错误和漏洞,而动态分析则是在程序运行时进行分析的过程,用来检测程序的性能和调试错误。
以下将分别介绍C语言中的静态分析和动态分析技巧。
静态分析技巧主要包括代码审查、静态代码分析工具和静态代码检查。
代码审查是由程序员或团队成员对代码进行逐行检查,以发现潜在的错误和改进代码质量。
这种方法虽然效果显著,但耗时耗力。
静态代码分析工具则是利用专门的软件工具对代码进行全面的分析,识别潜在的问题,并提供改进建议。
常用的静态代码分析工具包括Lint、Pylint、Coverity等。
静态代码检查是一种自动化工具,可以在编译代码时发现潜在的问题,并生成相应的报告。
开发人员可以根据报告进行适当的调整和改进代码。
动态分析技巧主要包括性能分析和调试。
性能分析是通过对程序运行时的各个方面进行监测和测量,以确定程序的性能瓶颈并优化程序性能。
常用的性能分析工具包括Valgrind、Gprof、Perf等。
调试是通过跟踪程序的执行过程,诊断程序中的错误和异常行为。
常用的调试工具包括GDB、LLDB等。
通过这些工具,开发人员可以更容易地找到程序中的bug,调试程序,并提高程序性能。
总的来说,静态分析和动态分析技巧在C语言编程中都是非常重要的。
静态分析可以提前发现潜在的问题,保证代码质量,而动态分析则可以帮助调试程序,优化程序性能。
开发人员可以根据具体的需求选择不同的分析技巧,以提高代码质量和程序性能。
希望以上介绍对您有所帮助,欢迎您进一步深入学习和探讨C语言中的静态分析和动态分析技巧。
【Java动态编译】动态编译的应⽤1、动态编译动态编译,简单来说就是在Java程序运⾏时编译源代码。
从JDK1.6开始,引⼊了Java代码重写过的编译器接⼝,使得我们可以在运⾏时编译Java源代码,然后再通过类加载器将编译好的类加载进JVM,这种在运⾏时编译代码的操作就叫做动态编译。
静态编译:编译时就把所有⽤到的Java代码全都编译成字节码,是⼀次性编译。
动态编译:在Java程序运⾏时才把需要的Java代码的编译成字节码,是按需编译。
静态编译⽰例:静态编译实际上就是在程序运⾏前将所有代码进⾏编译,我们在运⾏程序前⽤Javac命令或点击IDE的编译按钮进⾏编译都属于静态编译。
⽐如,我们编写了⼀个xxx.java⽂件,⾥⾯是⼀个功能类,如果我们的程序想要使⽤这个类,就必须在程序启动前,先调⽤Javac编译器来⽣成字节码⽂件。
如果使⽤动态编译,则可以在程序运⾏过程中再对xxx.java⽂件进⾏编译,之后再通过类加载器对编译好的类进⾏加载,同样能正常使⽤这个功能类。
动态编译⽰例:JDK提供了对应的JavaComplier接⼝来实现动态编译(rt.jar中的javax.tools包提供的编译器接⼝,使⽤的是JDK⾃带的Javac编译器)。
⼀个⽤来进⾏动态编译的类:public class TestHello {public void sayHello(){System.out.println("hello word");}}编写⼀个程序来对它进⾏动态编译:public class TestDynamicCompilation {public static void main(String[] args) {//获取Javac编译器对象JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();//获取⽂件管理器:负责管理类⽂件的输⼊输出StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);//获取要被编译的Java源⽂件File file = new File("/project/test/TestHello.java");//通过源⽂件获取到要编译的Java类源码迭代器,包括所有内部类,其中每个类都是⼀个JavaFileObjectIterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjects(file);//⽣成编译任务pilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits);//执⾏编译任务task.call();}}启动main函数,会发现在程序运⾏过程中,使⽤了Javac编译器对类TestHello进⾏了编译,并⽣成了字节码⽂件TestHello.class。
本文由我司收集整编,推荐下载,如有疑问,请与我司联系如何做到linux 下opencv 程序的静态编译2009/08/27 10 第一,程序是没有问题的,用的是官方网站的人脸检测的源代码,使用编译命令g++`pkg-configopencv--libs--cflagsopencv`facedect.cpp-ofacedect 编译出来的可执行文件,是可以检测出人脸区域的。
第二.我想把静态编译该程序,使用了以下编译命令g++-I/usr/local/include/opencv-L/usr/local/lib:/usr/lib:/libfacedect.cpp-ofacedect/usr/local/lib/libhighgui.a/usr/local/lib/libcv.a/usr/local/lib/libcxcore.a/usr/local/li b/libcvaux.a/usr/local/lib/libml.a/usr/lib/libgio-2.0.a 结果出了一堆错误:/usr/local/lib/libhighgui.a(window_gtk.o):Infunct ion`icvOnKeyPress’:/home/apple/tools/o pencv-1.0.0/otherlibs/highgui/window_gtk.cpp:1085:undefinedreferenceto`g_threads_got_initiali zed’/home/apple/tools/opencv-1.0.0/otherlibs/highgui/window_gtk.cpp:1085:undefinedreferenceto`g_thread_functions_fo r_gli b_use’/home/apple/tools/opencv-1.0.0/otherlibs/highgui/window_gtk.cpp:1093:undefinedreferenceto`g_thread_functions_fo r_glib_use’/home/apple/tools/opencv-1.0.0/otherlibs/highgui/window_gtk.cpp:1094:undefinedreferenceto`g_thread_functions_fo r_glib_use’/usr/local/lib/libhighgui.a(window_gtk.o):Infunction`cvWaitKey’:/home/apple/ tools/opencv-1.0.0/otherlibs/highgui/window_gtk.cpp:1251:undefinedreferenceto`g_timeout_add’/home /apple/tools/opencv-1.0.0/otherlibs/highgui/window_gtk.cpp:1253:undefinedreferenceto`gtk_main_iteration_d o’/home/apple/tools/opencv-1.0.0/otherlibs/highgui/window_gtk.cpp:1257:undefinedreferenceto`g_source_remove’/ho me/apple/tools/opencv-1.0.0/otherlibs/highgui/window_gtk.cpp:1224:undefinedreferen ceto`g_thread_self’/home/a。
GCC编译步骤及静态库动态库制作GCC是一种广泛使用的编译器,可以将C、C++等高级语言源代码转换为可执行的机器码。
本文将介绍GCC编译步骤及制作静态库和动态库的过程。
1. 预处理(Preprocessing):预处理器会处理源代码,根据预编译指令进行操作,例如宏展开、条件编译等。
预处理后的代码仍然是源代码,只是进行了一些文本替换和宏展开操作。
3. 汇编(Assembling):汇编器将汇编语言转换为机器码,生成目标文件(Object Files)。
目标文件包含可执行代码的二进制表示,以及与其他目标文件和库文件链接的信息。
4. 链接(Linking):链接器将多个目标文件和库文件结合在一起,生成最终的可执行文件。
链接器会解析目标文件之间的引用和符号,将它们关联起来,并生成可执行文件。
静态库制作:静态库是一种包含可执行代码和函数的库文件,在链接时会将库文件中的代码复制到最终的可执行文件中。
静态库的制作分为以下几个步骤:1.编写库代码:创建一个或多个源文件,其中包含一些可重用的函数和类。
确保将库代码编写成独立的、可移植的模块。
2. 编译库代码:使用GCC进行编译,将源代码文件编译成目标文件。
例如,对于C文件使用以下命令编译为目标文件:`gcc -c file1.cfile2.c`。
3. 归档库文件:将目标文件归档成库文件。
使用GCC进行归档时,可以使用`ar`命令。
例如,使用以下命令将目标文件归档:`ar rcs libmylib.a file1.o file2.o`。
这将创建名为libmylib.a的静态库文件。
4. 使用库文件:在需要使用库函数的程序中,包含库的头文件,并在链接时将库文件链接到程序中。
例如,使用以下命令编译和链接程序:`gcc -o myprog myprog.c -L. -lmylib`。
其中,-L参数指定库文件的路径,-l参数指定要链接的库文件。
在程序中使用库函数时,只需包含相应的头文件,并调用库函数。
一、概述CMake是一个跨评台的自动化建构系统,用于管理软件建构流程。
OpenCV是一个开源计算机视觉库,提供了丰富的功能,包括图像处理、计算机视觉、机器学习等。
Viz模块是OpenCV库中的一个3D 可视化模块,用于可视化和交互式操作3D数据。
本文旨在介绍如何使用CMake编译OpenCV中的Viz模块,以便开发者能够更好地了解和使用该模块。
二、准备工作1. 安装CMake需要在计算机上安装CMake。
可以从CMake官方全球信息湾上下载适合你操作系统的安装包,并按照官方指南进行安装。
安装完成后,可以在命令行中使用cmake命令。
2. 下载OpenCV源代码前往OpenCV官方全球信息湾下载最新的OpenCV源代码,并解压到你喜欢的目录。
3. 确认系统环境在开始编译前,需要确认你的系统环境已经安装了必要的编译工具和依赖项,比如C++编译器、图形库、线程库等。
这些依赖项的安装方法因操作系统而异,可以在OpenCV官方全球信息湾上找到对应的安装指南。
三、编译Viz模块1. 创建build目录在OpenCV源代码目录外创建一个build目录,用于存放编译生成的文件。
这样做可以保持源代码目录的干净,方便管理。
2. 运行CMake在命令行中进入build目录,然后执行以下命令:```plaintextcmake /path/to/opencv/source```这里的"/path/to/opencv/source"是你的OpenCV源代码目录的路径。
CMake会根据系统环境和配置文件生成一些中间文件,并输出一个Makefile,用于后续的编译操作。
3. 配置选项在运行CMake时,你可以添加一些选项来控制编译过程。
可以使用"-D WITH_VTK=ON"来启用VTK支持,"-DCMAKE_BUILD_TYPE=Release"来指定编译类型为Release等。
opencv 静态库使用方法
OpenCV是一个开源的计算机视觉库,它提供了丰富的图像处理和计算机视觉功能。
要使用OpenCV的静态库,你需要按照以下步骤进行操作:
1. 下载和安装OpenCV,首先,你需要从OpenCV官方网站下载OpenCV库,并按照官方文档提供的安装指南进行安装。
安装过程中需要注意选择编译静态库的选项。
2. 创建一个新的C++项目,在你的集成开发环境(IDE)中创建一个新的C++项目,例如使用Visual Studio或者CLion。
3. 配置项目属性,在项目属性中,你需要添加OpenCV的头文件路径和静态库文件路径。
这可以通过设置包含目录和库目录来实现。
4. 链接OpenCV静态库,在项目属性中,你需要指定要链接的OpenCV静态库名称,这些库文件通常以“lib”开头,以“.lib”为后缀。
你可以在链接器设置中指定这些库文件。
5. 编写代码,现在你可以开始编写使用OpenCV函数的代码了。
记得包含OpenCV的头文件,并使用OpenCV的命名空间。
6. 编译和运行,完成以上步骤后,你可以编译你的项目并运行
程序了。
确保你的程序能够正常链接OpenCV静态库并调用其中的函数。
需要注意的是,使用OpenCV的静态库可能会增加你的程序的体积,因为所有的函数和依赖项都会被静态链接到你的程序中。
另外,不同版本的OpenCV可能需要不同的配置和设置,所以建议在使用之
前仔细阅读官方文档和参考资料。
希望这些步骤能够帮助你成功使
用OpenCV的静态库。
cmakeqmakemakefile动态和静态库教程makefileMakefile经典教程(掌握这些⾜够)规则:makefile的基本规则就是:1. target 设定编译的target和各种的依赖⽂件已经如何从⽂件⽣成target的命令target : prerequisites ...commandtarget: 可以是object file,也可以是可执⾏⽂件,也可以是标签labelprerequisites: ⽣成target需要的⽂件或者其它的target; make 命令会检查这些依赖和上⼀次make相⽐是否有了改动,来决定这个target是否要重新更新。
command : 任何的shell命令,command⼀定要⽤Tab键开头。
对于command,GNU的make定义了⼀些隐含的规则,因此有的时候也可以不需要提供command,只提供target和依赖,GNU Make会⾃动调⽤隐含的规则(command):GNU的make很强⼤,它可以⾃动推导⽂件以及⽂件依赖关系后⾯的命令,于是我们就没必要去在每⼀个[.o]⽂件后都写上类似的命令,因为,我们的make会⾃动识别,并⾃⼰推导命令。
⽐如:a.o : a.c不需要提供command,make会⾃动使⽤gcc来⽣成以上就是最核⼼的makefile的规则。
2. 常⽤的语法(1) \ 反斜杠:换⾏符合a.c \b.c(2) 变量定义objects = a.o b.o c.o在使⽤的时候: $(objects)来调⽤这个变量(3) .PHONY : label.PHONYb表⽰后⾯的是⼀个伪⽬标,、(4) 注释 : #(5) make 命令会在当前⽬录下⾃动找: GNUmakefile, makefile, Makefile⽂件进⾏编译,如果要指定可以使⽤ “ make -f xxx”或者 make --file xxx(6) include : include可以把其他的makefile包括到当前的makefile中。
使用VS2015编译以及静态编译opencv3记录一直不知道怎样静态编译opencv并连接使用,网上的教程很零散,这里做个总结记录。
下载opencv3git clone https:///Itseez/opencv.git打开CMAKE-GUI,选择源码路径和构建路径点击configure,选择合适的编译器,有两个选项可选,x86以及x64。
编译两个版本的时候需要分别选择。
点击Finish后取消以下的一些选项上边是对应于编译动态链接库版本的,如果编译静态链接库版本,需要取消以下选项为了opencv的最终生成的库打包成一个world,需要选择如下选项最后点击generate即可在VS2015里点击生成,批生成选择如上两个INSTALL,点击生成。
然后再到目录下边查看install目录即可把文件复制到指定目录,然后把x86/vc14/bin添加到path里。
下边记录使用静态编译以及动态链接库的不同一般来说,一旦在cmake设置了BUILD_SHARE_LIBRARY选项,就是要编译dll,此时,在VS2015里,对于各个编译的解决方案,有的是编译成lib,有的是dll,譬如如下两项他们在代码生成都是MDd(Debug),MD(release)也就是vs2015的组件也是动态链接的。
而库的生成方式有同时也有一些是编译成静态库,但是这些配置不统一,最后出来的用的是动态链接的库。
此时不能随意更改选项,我原来这里以为改了选项就可以编译成静态库,这样是会编译错误的,因为cmake配置好的是动态库的选项。
如果需要配置静态库的选项,则需要重新运行cmake,取消如下选项,这个时候,所有的代码生成配置就是MTd,或者MT。
也就是说VS2015的组件库是静态链接进去的,在裸机上不会提示说缺少vsxxx140d.dll之类。
这个时候,可以发现所有都是lib静态库配置编译完成后,静态库会在staticlib文件夹中出现而动态编译的时候,则出现在bin目录会出现opencv的dll对于在实际编程后配置的时候如果是静态的配置,单击右键,属性设置如图所示的包含目录以及库目录,如果是用到静态库,就包含staticlib,如果是用到动态库,就只包含lib,同时包含会出现问题。
NDK编译依赖opencv静态库的arm64-v8a动态库遇到的问题:写完Android.mk和Application.mk⽂件,然后使⽤cygwin+NDK编译总是遇到下⾯的编译错误:fatal error: opencv2/core.hpp: No such file or directory#include "opencv2/core.hpp"在⽹上试了很多⽅法,都不奏效。
最终解决问题的办法是:将opencv和opencv2⽂件夹复制到这个⽬录:D:\android-ndk-r17c\sysroot\usr\include然后编译通过了。
因为引⼊opencv时代码是这样写的:#include "opencv2/core.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/objdetect/objdetect.hpp"#include "opencv2/ml/ml.hpp"#include "opencv2/imgproc/imgproc.hpp"编译器要去⾃⼰能查找的路径去搜索,很明显的搜索路径就是NDK路径,所以这个⽅法奏效了。
使⽤NDKr17c编译,其中opencv和opencv2⽂件夹复制到了D:\android-ndk-r17c\sysroot\usr\include⽂件夹下解决编译找不到⽂件问题。
在使⽤NDKr10e编译,由于没有sysroot⽂件夹,考虑到mk⽂件中配置编译器4.9和使⽤-std=c++11,于是找到下⾯这个路径,将opencv和opencv2⽂件夹复制到下⾯的路径同样解决了"opencv2/core.hpp"等opencv头⽂件找不到的问题。
D:\android-ndk-r10e\sources\cxx-stl\gnu-libstdc++\4.9\include可能这不是最好的解决问题的办法,但这是⼀个奏效的⽅法。
一、介绍OpenCVOpenCV是一个开源计算机视觉库,提供了丰富的图像处理和计算机视觉功能,方便用户实现各种图像处理和分析任务。
二、Makefile编译概述Makefile是用于管理项目编译的工具,可以通过编写Makefile文件来指定编译过程中的各种操作,包括编译参数、依赖关系、目标文件等。
三、使用Makefile编译OpenCV1. 配置Makefile在使用Makefile编译OpenCV之前,首先需要配置Makefile文件。
可以根据项目的具体需求,编写Makefile文件,指定编译参数、依赖关系等信息。
2. 编译OpenCV编译OpenCV需要使用命令行工具,进入OpenCV源代码目录下,执行相应的Makefile文件,即可开始编译OpenCV。
3. 编译参数设置在Makefile文件中,可以设置编译参数,包括编译器选项、信息选项、库文件路径等。
根据项目的需求,可以灵活设置编译参数,以满足项目的编译要求。
4. 依赖关系设置Makefile中可以指定文件之间的依赖关系,确保在编译过程中,各个文件的编译顺序和依赖关系得到正确的处理。
5. 目标文件生成通过Makefile编译OpenCV时,可以指定生成的目标文件,包括可执行文件、静态库、动态库等。
根据项目的需求,可以设置目标文件的生成规则。
6. 编译错误处理在使用Makefile编译OpenCV时,可能会遇到编译错误。
需要及时分析错误信息,调整Makefile文件,解决编译错误,确保编译顺利完成。
7. 其他注意事项在使用Makefile编译OpenCV时,需要注意文件路径、库文件依赖、编译器版本等因素,确保编译过程正确无误。
四、总结Makefile是管理项目编译的重要工具,通过编写Makefile文件,可以指定各种编译操作,灵活控制项目的编译过程。
在编译OpenCV时,合理配置Makefile文件,可以提高编译效率,确保项目的顺利编译和运行。
一、序言当一个opencv工程实现之后,我们会面临一个问题,怎么把opencv程序的exe在其他电脑上运行,这个问题已经有很多人遇到过,当然也有很多人给出了博客,介绍了具体的解决方法,具体自己操作时,还是遇到了这样或者那样的小毛病,不过凭借自己根据错误提示解决问题的能力,最后还是把静态编译给编译成功了。
本文介绍两种opencv程序移植到其他电脑运行的方法,一种是动态编译,需要拷贝程序运行需要的dll,也就是-个exe跟着多个dll的模式,这种简单粗暴,但是显得拖拖拉拉,一个程序还得跟着那么多其他文件,所以我们很不推荐。
另外一种就是本文主要介绍的静态编译,和之前运行不一样,我们在这使用的不是opencv的lib库,而是staticlib,编译成功之后,程序只需要拷贝一个exe,就可以在其他电脑上运行。
另外介绍一下本文测试程序工作的程序配置操作系统Win7IDE VS2010opencv版本opencv2.4.5二、动态编译为了做一个全面的总结,在这简单的介绍opencv动态编译的方法。
opencv动态编译需要两部分dll:(1)opencv库的dll,检查你所引用的h文件,把对应的dll,拷贝过来就行,注意debug和release的不同,当然一般程序发布的话都会用release版本的,因为release版本比debug版本要快10倍有余。
(2)考虑到目标终端有可能没有装vs,所以需要拷贝msvcp110.dll和msvcr110.dll(release下),dll在C:/Windows/System32下。
三、静态编译静态编译主要的不同就是利用的是H:/Opencv2.4.5/opencv/build/x86/vc11/staticlib文件下的lib,而非H:/Opencv2.4.5/opencv/build/x86/vc11/lib文件夹。
具体配置如下:1.新建空项目,项目名称Static_Opencv2.新建cpp,写入一个简单opencv测试程序:#include <opencv2/core/core.hpp>#include<opencv2/highgui/highgui.hpp>using namespace cv;void main(){ cv::Mat image = cv::imread("img1.png"); cv::flip(image,image,1);cv::imwrite("flip.jpg",image);}3.新建一个属性管理器视图-》属性管理器-》Debug-》右键-》添加新项目属性表属性表名称改为PropertySheet_Static_Opencv_debug。
最好的解释1静态编译就是在编译的时候把你所有的模块都编译进exe里去,当你启动这个exe的时候所有模块都加载进来了。
你写小程序没问题,但程序一大,加载的过程(就是当你运行程序时初始化的过程)就比较费力了。
大多数ppc的硬件配置还是很一般的。
动态编译就不一样了,你编译的时候那些模块都没有编译进去,一般情况下你可以把那些模块都编译成dll,这样你启动程序(初始化)的时候这些模块不会被加载,而是在运行的时候,用到那个模块就调用哪个模块。
简单的打个比方,我写个阅读器,支持txt,pdf,udm三种格式,暂时把读txt,读pdf,读udm定义为三个功能模块。
使用静态编译:我想看个txt,点击应用程序图标以后三个功能都加载进来了,判断格式,使用读txt模块。
(在这里,另外两个模块的作用就是占用系统资源。
-。
-)使用动态编译:我想看个txt,点击应用程序,判断格式,只加载读txt模块,使用读txt模块。
显然,动态编译1速度快,2节省了系统资源,3利于今后拓展。
解释2静态编译的话exe文件运行的时候不会用到别的文件动态编译exe文件就要用到别的文件了解释3一个是租自行车,什么时候骑什么时候租,有新车就租新车,没新车就租旧车,有电动车就省点劲,碰上没车座子的就扎屁股,人家不出租了你就别用了。
一个是自己买个自行车天天扛着,进电梯上地铁也扛着。
老子自己的...解释4用静态链接库编译,相当于你带着一个工具包到处跑(遇到有需要的地方不需要周围的环境提供相应的工具,自己用自己工具包的工具就行了,所以当环境发生变化可以尽可能的无视),当然,你本来不带任何东西走到哪是哪和工具包随身带的区别显然就是重量增加了,即程序的体积可能会比另一种方式来的大一点,看你的工具包有多大了。
静态编译与动态编译背景:使⽤静态库完成如下程序:输⼊⼀个菱形半径,打印菱形。
=====》main.c输⼊整数封装成IOTool==========》iotool.c菱形的打印封装成Graphics=======》graphics.c计划:1.实现输⼊2.实现菱形3.编译静态库4.调⽤静态库iotool.c代码#include <stdio.h>int inputInt(const char *info){int r;printf("%s:",info);scanf("%d",&r);return r;}graphics.c代码#include <stdio.h>void diamond(int r){int x,y;for(y=0;y<=2*r;y++){for(x=0;x<=2*r;x++){if(y==x+r || y==x-r|| y==-x+r || y==-x+3*r){printf("*");}else{printf(" ");}}printf("\n");}} 此处应有掌声。
这是⼀个算法,利⽤坐标轴来分别画出菱形的四条边。
main.c函数#include <stdio.h>#include <unistd.h>main(){int r=inputInt("输⼊菱形半径");diamond(r);printf("%d\n",getpid());while(1);}静态库的编译编译过程: gcc -c -static -iotool.c gcc -c -static -graphics.c归档成静态库: ar -r libdemo.a iotool.o grahics.o查看函数符号表:nm libdemo.a使⽤静态库: gcc main.c -o main -l demo -L .运⾏程序: main1.编译过程(*.a achieve)1.1.编译成⽬标⽂件-static 可选gcc -c -static 代码⽂件.c1.2.归档成静态库ar⼯具ar -r-tar -r 静态库⽂件被归档的⽂件nm⼯具(察看函数符号表)nm 静态库或者动态库或者⽬标⽂件或者执⾏⽂件1.3.使⽤静态库gcc 代码静态库总结:1.什么是库?函数等代码封装的⼆进制已经编译的归档⽂件2.ar归档⼯具3.采⽤库的⽅式管理代码优点:容易组织代码复⽤保护代码版权4.静态库的静态的含义:编译好的程序运⾏的时候不依赖库。
动态编译和静态编译,共享库简介静态函数库⼀般扩展名为(.a),这类的函数库通常扩展名为libxxx.a 。
这类函数库在编译的时候会直接整合到程序中,所以利⽤静态函数库编译成的⽂件会⽐较⼤,这类函数库最⼤的优点就是编译成功的可执⾏⽂件可以独⽴运⾏,⽽不再需要向外部要求读取函数库的内容;但是从升级难易度来看明显没有优势,如果函数库更新,需要重新编译。
动态函数库动态函数库的扩展名⼀般为(.so),这类函数库通常名为libxxx.so 。
与静态函数库被整个捕捉到程序中不同,动态函数库在编译的时候,在程序⾥只有⼀个“指向”的位置⽽已,也就是说当可执⾏⽂件需要使⽤到函数库的机制时,程序才会去读取函数库来使⽤;也就是说可执⾏⽂件⽆法单独运⾏。
⼀般,在程序第⼀次执⾏或者第⼀次调⽤的时候,可能会在加载链接库的时候慢点,但这样减少看每个可执⾏⽂件的长度, ⽽且其他的程序如果发现内存中已经存在这个链接库的时候就不需要再次加载了。
另外,使⽤共享库的可以使⽤库函数来迭代更新,应⽤程序将⽆需更改,只要函数的接⼝不变。
例⼦第1步:编辑得到举例的程序hello.h、hello.c和main.c;hello.h (见程序1)为该函数库的头⽂件。
hello.c (见程序2)是函数库的源程序,其中包含公⽤函数hello,该函数将在屏幕上输出"Hello XXX!"。
main.c (见程序3)为测试库⽂件的主程序,在主程序中调⽤了公⽤函数hello。
--------------------------------------------------------------------------------程序1: hello.h#ifndef HELLO_H#define HELLO_Hvoid hello(const char *name);#endif //HELLO_H--------------------------------------------------------------------------------程序2: hello.c#include <stdio.h>void hello(const char *name){printf("Hello %s!\n", name);}--------------------------------------------------------------------------------程序3: main.c#include "hello.h"int main(){hello("everyone");return 0;}--------------------------------------------------------------------------------第2步:将hello.c编译成.o⽂件在系统提⽰符下键⼊以下命令得到hello.o⽂件。
Java代码的静态编译和动态编译中的问题比较Java应用程序的性能经常成为开发社区中的讨论热点。
因为该语言的设计初衷是使用解释的方式支持应用程序的可移植性目标,早期Java运行时所提供的性能级别远低于C 和C++之类的编译语言。
尽管这些语言可以提供更高的性能,但是生成的代码只能在有限的几种系统上执行。
在过去的十年中,Java 运行时供应商开发了一些复杂的动态编译器,通常称作即时(Just-in-time,JIT)编译器。
程序运行时,JIT 编译器选择将最频繁执行的方法编译成本地代码。
运行时才进行本地代码编译而不是在程序运行前进行编译(用 C 或C++编写的程序正好属于后一情形),保证了可移植性的需求。
有些JIT 编译器甚至不使用解释程序就能编译所有的代码,但是这些编译器仍然通过在程序执行时进行一些操作来保持Java 应用程序的可移植性。
由于动态编译技术的多项改进,在很多应用程序中,现代的JIT 编译器可以产生与C 或C++ 静态编译相当的应用程序性能。
但是,仍然有很多软件开发人员认为——基于经验或者传闻——动态编译可能严重干扰程序操作,因为编译器必须与应用程序共享CPU。
一些开发人员强烈呼吁对Java 代码进行静态编译,并且坚信那样可以解决性能问题。
对于某些应用程序和执行环境而言,这种观点是正确的,静态编译可以极大地提高Java 性能,或者说它是惟一的实用选择。
但是,静态地编译Java 应用程序在获得高性能的同时也带来了很多复杂性。
一般的Java 开发人员可能并没有充分地感受到JIT 动态编译器的优点。
本文考察了Java 语言静态编译和动态编译所涉及的一些问题,重点介绍了实时(RT) 系统。
简要描述了Java 语言解释程序的操作原理并说明了现代JIT 编译器执行本地代码编译的优缺点。
介绍了IBM 在WebSphere Real Time 中发布的AOT 编译技术和它的一些优缺点。
然后比较了这两种编译策略并指出了几种比较适合使用AOT 编译的应用程序领域和执行环境。
C#代码动态编译、动态执行、动态调试头几天看到一篇关于动态编译的文章 ,很受启发。
在此基础上我做了一些封装,为使挪用加倍简单,并增加了对动态代码调试的支持,相同代码只编译一次的支持,代码改动自动从头编译,代码引用文件的自动加载和手工加载等功能。
如上图,我封装的类CSharpProvider很简单,下面说明一下一些公共成员的用法。
公共属性AssemblyFileName:那个属性指定动态编译后生成的配件名称。
CompilerParameters:那个属性指定编译的参数References:那个属性指定被编译代码中的引用。
挪用者只要挪用(""),就能够够加入自己的引用,关于System命名空间的所有引用,不需要手工加入,该类会自动加载。
关于用户自己的组件,若是不手工指定引用文件,该类会自动依照名字空间名进行猜想。
SourceCodeFileEncoding:若是以文件形式编译,指定文件的编码类型。
公共方式public bool Compile(string code)输入代码字符串,并编译public bool CompileFromFile(string sourceCodeFileName)编译输入的代码文件public object CreateInstance(string code, string typeFullName)创建类的实例如下面代码,能够输入CreateInstance(code, ""),也能够输入CreateInstance(code, "HelloWorld"),程序会依照类型名称来自动找到符合条件的类并实例化。
若是代码中有多个指定类型的类,将实例化第一个。
using System;using MyInterface;[Serializable]public class HelloWorld : MarshalByRefObject, IHelloWorld{public string Say(){return"Hi";}}那个地址需要专门指出的是由于用到了AppDomain的远程挪用,所有的动态加载的代码必需继承自MarshallByRefObject若是仅仅声明为[Serializable] 尽管也能够执行,但主应用程序域会记录下子应用程序域的一个引用,如此致使子应用程序域卸载后,仍然无法完全释放内存,从而内存泄漏。
一、序言
当一个opencv工程实现之后,我们会面临一个问题,怎么把opencv程序的exe在其他电脑上运行,这个问题已经有很多人遇到过,当然也有很多人给出了博客,介绍了具体的解决方法,具体自己操作时,还是遇到了这样或者那样的小毛病,不过凭借自己根据错误提示解决问题的能力,最后还是把静态编译给编译成功了。
本文介绍两种opencv程序移植到其他电脑运行的方法,一种是动态编译,需要拷贝程序运行需要的dll,也就是-个exe跟着多个dll的模式,这种简单粗暴,但是显得拖拖拉拉,一个程序还得跟着那么多其他文件,所以我们很不推荐。
另外一种就是本文主要介绍的静态编译,和之前运行不一样,我们在这使用的不是opencv的lib库,而是staticlib,编译成功之后,程序只需要拷贝一个exe,就可以在其他电脑上运行。
另外介绍一下本文测试程序工作的程序配置
操作系统Win7
IDE VS2010
opencv版本opencv2.4.5
二、动态编译
为了做一个全面的总结,在这简单的介绍opencv动态编译的方法。
opencv动态编译需要两部分dll:
(1)opencv库的dll,检查你所引用的h文件,把对应的dll,拷贝过来就行,注意debug和release的不同,当然一般程序发布的话都会用release版本的,因为release版本比debug版本要快10倍有余。
(2)考虑到目标终端有可能没有装vs,所以需要拷贝msvcp110.dll和msvcr110.dll(release下),dll在C:/Windows/System32下。
三、静态编译
静态编译主要的不同就是利用的是
H:/Opencv2.4.5/opencv/build/x86/vc11/staticlib文件下的lib,而非
H:/Opencv2.4.5/opencv/build/x86/vc11/lib文件夹。
具体配置如下:
1.新建空项目,项目名称Static_Opencv
2.新建cpp,写入一个简单opencv测试程序:
#include<opencv2/core/core.hpp>#include
<opencv2/highgui/highgui.hpp>using namespace cv;void main(){cv::Mat image=cv::imread("img1.png");cv::flip(image,image,1);
cv::imwrite("flip.jpg",image);}
3.新建一个属性管理器
视图-》属性管理器-》Debug-》右键-》添加新项目属性表
属性表名称改为PropertySheet_Static_Opencv_debug。
4.编辑属性表
右键属性表-》属性-》VC++目录-》包含目录,然后添加opencv的h文件目录:
库目录里面添加staticlib文件夹目录
然后C/C++-》代码生成-》运行库-》多线程调试(/MTd),
介绍一下这四个选项,多线程(/MT)为静态链接release模式,多线程调试(/MTd)为静态链接debug模式,多线程dll(/MD)为动态链接release模式,多线程调试DLL(/MDd)为动态链接debug模式。
5.最后在程序中添加#pragmatic,使用程序调用lib
完整的程序如下:
#include<opencv2/core/core.hpp>#include
<opencv2/highgui/highgui.hpp>#pragma comment(lib,
"IlmImfd.lib")#pragma comment(lib,"libjasperd.lib")#pragma
comment(lib,"libjpegd.lib")#pragma comment(lib,
"libpngd.lib")#pragma comment(lib,"libtiffd.lib")#pragma comment(lib, "zlibd.lib")#pragma comment(lib,"opencv_core245d.lib")#pragma comment(lib,"opencv_highgui245d.lib")#pragma comment(lib,
"vfw32.lib")#pragma comment(lib,"comctl32.lib")using namespace cv;void main(){cv::Mat image=cv::imread("img1.png");
cv::flip(image,image,1);cv::imwrite("flip.jpg",image);}
最后程序运行会出现很多warning,但是不影响运行,程序大小为7.5M!挺大的,但是一个大程序,总比一个exe跟着多个dll好啊。
6.程序运行结果原图:
结果图:。