精华内容
下载资源
问答
  • 2021-11-30 17:07:11
    root@anhui-k55vd:~/myqtPrj#python3
    Python 3.6.9 (default, Jan 26 2021, 15:33:00) 
    [GCC 8.4.0] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import ctypes
    >>> so =ctypes.cdll.LoadLibrary('./libcrachrecg.so')
    >>> 
    >>> so.hello()
    hello
    4.1.0

    上面代码是以调用libcrachrecg.so为例,,,hello函数为自己生成的so动态库里的接口函数。这个so中也用到opencv库中的函数。

    需要传递char*参数到so的函数时,也就是需要传递字符串到so的char*接收时,应该在python传入时在字符串的前面加个b,表示格式化为字节字符串类型,否则so的c++代码接收到的字符串出错。在python3中正常情况下,实例化一个字符串会得到一个str实例,而不是字节字符串,详细请到这里了解更多。

    >>> import ctypes
    >>> so = ctypes.cdll.LoadLibrary("./libcrachrecg.so")
    >>> 
    >>> imgPath = b"11.jpg"
    >>> outputDir = b"./imgPath"
    >>> outputImgName = b"123"
    >>> so.testFunction(None,imgPath,outputDir,outputImgName)
    1
    >>>
    >>>

    更多相关内容
  • Windows环境下软件有时会缺少依赖而无法正常运行,可使用depend工具查看当前EXE所依赖的所有
  • Windows/Linux链接器加载动态库的搜索路径顺序

    Windows/Linux链接器加载动态库的搜索路径顺序


    如需转载请标明出处:http://blog.csdn.net/itas109
    QQ技术交流群:129518033

    目录

    系统:Ubuntu 16.04.5 64bit
    系统:windows 7 64bit


    前言

    Windows/Linux程序运行时,其动态库的路径搜索是有顺序的。本文介绍其搜索顺序。

    1.Windows链接器加载动态库的搜索路径顺序

    通过隐式和显式链接,Windows首先搜索“已知DLL”,例如Kernel32.dll和User32.dll。 Windows然后按以下顺序搜索DLL:

    1. 当前进程的可执行模块所在的目录
    2. 当前目录
    3. Windows系统目录。如C:\Windows\System32,GetSystemDirectory函数检索此目录的路径
    4. Windows目录。 如C:\Windows,GetWindowsDirectory函数检索此目录的路径
    5. PATH环境变量中列出的目录

    英文原文:

    Windows then searches for the DLLs in the following sequence:
    1. The directory where the executable module for the current process is located.
    2. The current directory.
    3. The Windows system directory. The GetSystemDirectory function retrieves the path of this directory.
    4. The Windows directory. The GetWindowsDirectory function retrieves the path of this directory.
    5. The directories listed in the PATH environment variable.
    

    2.Linux链接器加载动态库的搜索路径顺序

    链接器使用以下搜索路径来查找所需的共享库:

    1. -rpath-link选项指定的任何目录。

    2. -rpath选项指定的任何目录。-rpath和-rpath-link之间的区别在于-rpath选项指定的目录包含在可执行文件中并在运行时使用,而-rpath-link选项仅在链接时有效。

    gcc main.c -rpath dir_path
    
    1. 在ELF系统上,对于本机链接器,如果是-rpath和-rpath-link选项未使用,搜索环境变量“LD_RUN_PATH”的内容。 在SunOS上,如果未使用-rpath选项,搜索指定的任何目录使用-L选项。

    2. 对于本机链接器,搜索环境变量的内容“LD_LIBRARY_PATH”。

    3. 对于本机ELF链接器,共享的“DT_RUNPATH”或“DT_RPATH”中的目录在库中搜索它所需的共享库。 “DT_RPATH”条目是如果存在“DT_RUNPATH”条目,则忽略。

    4. 默认目录,通常是/lib和/usr/lib。

    5. 对于ELF系统上的本机链接器,如果文件/etc/ld.so.conf存在,则列表在该文件中找到的目录。

    如果找不到所需的共享库,链接器将发出警告并且继续链接。

    英文原文:

    ld - The GNU linker
    
    -rpath-link=dir
               When using ELF or SunOS, one shared library may require another.  This happens when an
               "ld -shared" link includes a shared library as one of the input files.
    
               When the linker encounters such a dependency when doing a non-shared, non-relocatable
               link, it will automatically try to locate the required shared library and include it
               in the link, if it is not included explicitly.  In such a case, the -rpath-link option
               specifies the first set of directories to search.  The -rpath-link option may specify
               a sequence of directory names either by specifying a list of names separated by
               colons, or by appearing multiple times.
    
               This option should be used with caution as it overrides the search path that may have
               been hard compiled into a shared library. In such a case it is possible to use
               unintentionally a different search path than the runtime linker would do.
    
               The linker uses the following search paths to locate required shared libraries:
    
               1.  Any directories specified by -rpath-link options.
    
               2.  Any directories specified by -rpath options.  The difference between -rpath and
                   -rpath-link is that directories specified by -rpath options are included in the
                   executable and used at runtime, whereas the -rpath-link option is only effective
                   at link time. Searching -rpath in this way is only supported by native linkers and
                   cross linkers which have been configured with the --with-sysroot option.
    
               3.  On an ELF system, for native linkers, if the -rpath and -rpath-link options were
                   not used, search the contents of the environment variable "LD_RUN_PATH".
    
               4.  On SunOS, if the -rpath option was not used, search any directories specified
                   using -L options.
    
               5.  For a native linker, search the contents of the environment variable
                   "LD_LIBRARY_PATH".
    
               6.  For a native ELF linker, the directories in "DT_RUNPATH" or "DT_RPATH" of a shared
                   library are searched for shared libraries needed by it. The "DT_RPATH" entries are
                   ignored if "DT_RUNPATH" entries exist.
    
               7.  The default directories, normally /lib and /usr/lib.
    
               8.  For a native linker on an ELF system, if the file /etc/ld.so.conf exists, the list
                   of directories found in that file.
    
               If the required shared library is not found, the linker will issue a warning and
               continue with the link.
    

    Refrence:

    1. Search Path Used by Windows to Locate a DLL
    2. ld on ubuntu
    3. Using ld The GNU linker

    觉得文章对你有帮助,可以扫描二维码捐赠给博主,谢谢!
    在这里插入图片描述
    如需转载请标明出处:http://blog.csdn.net/itas109
    QQ技术交流群:129518033

    展开全文
  • Windows动态链接

    千次阅读 2020-03-10 19:44:08
    一、Windows动态链接简介 DLL即动态链接(Dynamic-Link Library)的缩写,相当于Linux下的共享对象。Windows系统中大量采用DLL机制,甚至内核的结构很大程度依赖于DLL机制。Windows下的DLL文件和EXE文件实际上...

    一、Windows的动态链接库简介

    DLL即动态链接库(Dynamic-Link Library)的缩写,相当于Linux下的共享对象。Windows系统中大量采用DLL机制,甚至内核的结构很大程度依赖于DLL机制。Windows下的DLL文件和EXE文件实际上是一个概念,都是PE格式的二进制文件。

    1.1 Windows下面的动态链接库与Linux下面的动态链接库的区别

    (1)文件后缀不同

    Linux动态库的后缀是 .so 文件,而window则是 .dll 文件

    (2)文件格式不同

    (a)Linux下是ELF格式,即Executable and Linkable Format。在ELF之下,共享库中所有的全局函数和变量在默认情况下都可以被其它模块使用,即ELF默认导出所有的全局符号。

    (b)Windows下面是PE格式的文件,即Portable Executable Format。DLL本质上也是PE文件,DLL需要显示地“告诉”编译器需要导出某个符号,否则编译器默认所有的符号都不导出。

    (c)动态链接库的文件个数不一样

    Linux的动态链接库就只有一个 .so 文件,还有与之对应的头文件,而在Windows下面的动态库有两个文件,一个是引入库(.LIB)文件,一个是动态库(.DLL)文件,需要的头文件(.h)文件。

    (1)引入库文件包含被DLL导出的函数的名称和位置,对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

    (2)DLL文件包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。

    总结:从上面的说明可以看出,Windows下面所创建的动态链接库DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。一般的动态库程序有lib文件和dll文件,lib文件是编译时期连接到应用程序中的,而dll文件才是运行时才会被调用的。

    1.2 静态链接库和动态链接库的异同点

    如果采用静态链链接库(.lib),lib中的指令最终都会编译到链接该静态库的exe(或dll)文件中,发布软件时,只需要发布exe(或dll)文件,不需要.lib文件。

    但是若使用动态链接库(. dll),dll中的指令不会编译到exe文件中,而是在exe文件执行期间,动态的加载和卸载独立的dll文件,需要和exe文件一起发布。

    静态链接库不能再包含其他动态链接库或静态链接库,而动态链接库不受此限制,动态链接库中可以再包含其他的动态链接库和静态链接库。

    来自:https://blog.csdn.net/w_y2010/article/details/80428067

    1.3 动态链接库的优点

    1)节省内存和代码重用:当应用程序使用动态链接时,多个应用程序可以共享磁盘上单个DLL副本

    2)可扩展性:DLL文件与EXE文件独立,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序

    3)复用性:DLL的编制与具体的编程语言以及编译器无关,不同语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数1

    1.4 有下面的代码

    • 头文件framework.h
    #pragma once
    namespace mycal
    {
    	int add(int a, int b);
    
    	int sub(int a, int b);
    }
    
    • 实现代码 framework.cpp
    //framework.cpp
    #include "framework.h"
    
    int mycal::add(int x, int y)
    {
    	return x + y;
    }
    
    int mycal::sub(int x, int y)
    {
    	return x - y;
    }
    

    在Linux下,编译成动态链接库之后,会得到一个 xxx.so 文件,现在只要引入头文件,包含动态库路径,就可以正常使用了,但是上面的代码同样在Windows下面,使用VS2017编译成动态链接库之后,的确不会报错,只会的到一个 xxx.dll 文件,(不是还有一个对应的 xxx.lib文件吗,哪里去了呢?)

    然后我们新建一个项目,按照 “头文件路径配置——库文件路径配置”的方法,编写代码,我们也可以调用到add这两个函数,还有语法提示,因为语法提示其实来自于头文件,和库文件没关系,但是编译却不成功了,显示调用的add以及sub都是错误的,这是为什么呢?

    这是因为前面说了Windows下面需要显式的告诉编译器,动态库中有哪一些函数是可以导出使用的,上面没有显示说明,即add和sub实际上是不可以使用的,故而会报错,怎么办呢?参见下面。

    二、Windows平台之下使用VS2017如何创建动态库

    2.1 解决未生成lib文件以及函数没有显式导出的问题

    两种方式来决定动态库中到底哪些函数是可以导出供外部直接使用的,以及与此同时生成与dll对应的 .lib 文件。

    (1)MSVC编译器提供了关键字_declspec,来指定指定符号的导入导出,即_declspec属性关键字

    _declspec(dllexport) 表示该符号是从本DLL导出的符号:这是在定义DLL中的函数等源代码是必须使用的,如果不显式的导出某一些符号,则使用动态链接库虽然没有语法上的错误,但是她无法编译,因为dll中的函数没有暴露出来,故而找不到。

    _declspec(dllimport)表示该符号是从别的DLL中导入的:我们在使用动态链接库DLL中暴露出来的函数的时候,可以直接使用暴露的函数,也可以通过显示地导入函数,编译器会产生质量更好的代码。由于编译器确切地知道了一个函数是否在一个DLL中,它就可以产生更好的代码,不再需要间接的调用转接。如下所示:

    //显式的导入dll中暴露出来的函数
    __declspec(dllimport) void func1(void);
    int main(void)
    {
    	func1();
    }
    

    后面会专门讲如何使用 __declspec 来创建动态库。

    (2)使用"xxx.def"文件来声明导入和导出符号

    我们也可以不使用__declspec 来创建动态库,我们就按照正常的程序编写,如第一章节里面的 myMath.h 和 myMath.cpp 里面的内容,然后显示的添加一个 xxx.def 文件,怎么添加呢?

    如下:右击项目/添加/新建项,选择如下的文件:
    在这里插入图片描述
    默认是使用source.def 我们可以自定义名称。关于这个def文件是如何规定哪些内容是导出的,哪一些是不导出的,这里暂时先不说明了,可以参考下面的几篇文章:

    https://blog.csdn.net/qwq1503/article/details/85696279

    http://www.cnblogs.com/enterBeijingThreetimes/archive/2010/08/04/1792099.html

    2.2 使用 __declspec 来创建动态库的完整过程

    (1)新建一个空项目或者是使用DLL模板都可以。

    • 添加头文件 framework.h
    //framework.h
    #pragma once
    
    #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
    // Windows Header Files
    #include <windows.h>
    
    namespace mycal {
    	__declspec(dllexport) int add(int a, int b);
    	__declspec(dllexport) int sub(int a, int b);
    }
    

    注意:实际上就是在需要定义的函数前面添加一个 __declspec(dllexport) 是两个短下划线开头哦!来表示这两个函数是暴露出来可以供直接使用的,没有暴露的函数,在动态链接库中是没办法使用的。

    2)实现函数的内容。

    • 定义一个 framework.cpp文件
    //framework.cpp
    #include "framework.h"
    
    int mycal::add(int x, int y)
    {
    	return x + y;
    }
    
    int mycal::sub(int x, int y)
    {
    	return x - y;
    }
    

    这个地方和我们平时的实现完全一样,实现的时候不再需要添加 __declspec(dllexport) 了。

    (3)生成项目

    比如我选择生成 Debug x64位的结果,

    生成之后得到如下的结果:
    在这里插入图片描述
    我们发现有一对配套的 xxx.dll 和 xxx.lib 文件,他们的大小不一样哦!此lib文件只是dll文件中导出函数的声明和定位信息,并不包含函数的实现,因此此lib文件只是在调用对应dll库的工程编译时使用,不需要随exe发布。

    三、动态链接库的使用

    3.1 静态调用dll

    静态调用是由编译系统完成对dll文件的加载和应用程序结束时完成对dll的卸载,当调用某dll的应用程序结束时,则windows系统对该dll的应用记录减1,直到使用该dll的所有应用程序都结束,即对该dll应用记录为0,操作系统会卸载该dll,静态调用方法简单,但不如动态调用适用。

    前面说了,window上生成的动态链接库的使用需要三个东西:头文件,dll文件,与dll对应的lib文件。

    这里都具备了,现在新建一个项目,如何配置呢?

    三步走配置

    (1)第一步:配置包含路径——即头文件所在的路径,将头文件复制过来。
    在这里插入图片描述

    (2)第二步:配置库路径——即lib所在的路径,将Dll_demo_1.lib也复制到当前工程文件夹中。
    在这里插入图片描述

    (3)第三步:添加链接,——将上面得到的Dll_demo_1.lib添加到链接器:

    #pragma comment(lib,"Dll_demo_1.lib")
    

    这一句是告诉编译器与该dll相对应的.lib文件所在的路径和文件名。在生成dll文件时,链接器会自动为其生成一个对应的.lib文件,该文件包含了dll导出函数的符号名和序号(并没有实际的代码)。在应用程序中,.lib文件将作为dll的替代文件参与编译,编译完成后,.lib文件就不需要了。

    修改复制过来的 framework.h,将里面的__declspec(dllexport)为__declspec(dllimport):

    #pragma once
    #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
    // Windows Header Files
    #include <windows.h>
    
    namespace mycal {
    	__declspec(dllimport) int add(int a, int b);
    	__declspec(dllimport) int sub(int a, int b);
    }
    

    Source.cpp 代码如下:

    #include <iostream>
    #include <myMath.h> //添加自己定义的头
    #pragma comment(lib,"Dll_demo_1.lib")
    int main()
    {
    	int x = 50;
    	int y = 10;
    	int a,b;
    	a = mycal::add(x, y);
    	b = mycal::sub(x, y);
    	printf("%d %d\n", a, b);
    	getchar();
    	return 0;
    }
    

    现在生成,生成没有错误,但是运行依然会报错,因为运行的时候需动态链接库,所以还需要配置动态链接库。

    一共有三种方式,本文采用最简单的方式,直接将动态链接库和可执行exe文件拷贝到一起即可。
    在这里插入图片描述
    然后运行上面的程序,得到结果如下:

    120 80
    上面就是整个动态链接库的创建以及使用的过程。

    注意1

    1)可以修改.lib文件的文件名,只要在项目引用它时,使用它目前的名称,便可以正确运行,但不能改变.dll文件的名字,不然也会出现找不到.dll文件的错误

    2).dll文件必须和.exe放在一起,.exe文件在哪里.dll文件也得在那里,两者“共存亡”,否则就会出现找不到.dll文件的错误

    3)和静态库一样,.dll文件也要和应用程序的位数相对应,要么都是64位的,要么都是32位的,不可交叉使用。

    4)静态调用不需要使用Win32API函数来加载和卸载Dll以及获取Dll中导出函数的地址,这是因为当通过静态链接方式编译生成程序时,编译器会将.lib文件中导出函数的函数符号链接到生成的exe文件中,.lib文件中包含的与之对应的dll文件的文件名也被编译存储在exe文件内部,当应用程序运行过程中需要加载dll文件时,windows将根据这些信息查找并加载dll,然后通过符号名实现对dll函数的动态链接,这样,exe将能直接通过函数名调用dll 的输出函数,就像调用程序内部的其他函数一样。

    3.2 动态调用dll

    动态调用是由程序员调用系统API函数加载和卸载dll,程序员可以决定dll文件何时加载,何时卸载,加载哪个dll文件,将dll文件的使用权完全交给程序员。

    1)、新建控制台项目,添加 main.cpp 文件,将刚刚生成的 Dll_demo_1.dll 文件拷贝到项目目录下,main.cpp 代码如下

    #include "stdio.h"
    #include <windows.h>
    
    typedef int (*lpAddFun)(int ,int );//宏定义函数指针类型
    
    int main()
    {
    	HINSTANCE hDll;//DLL 句柄
    	lpAddFun addFun;//函数指针
    	hDll = LoadLibrary(L"Dll_demo_1.dll");//动态获取dll文件的路径
    	if (hDll!=NULL)
    	{
    		addFun =(lpAddFun)GetProcAddress(hDll,"add");//根据函数名在dll文件中获取该函数的地址	
    		if (addFun!=NULL)
    		{
    			int result =addFun(2,3);
    			printf("2+3=%d",result);
    		}
    
    	FreeLibrary(hDll);
    	}
    	return 0;
    }
    

    运行结果:2+3=5

    3.2.1 main.cpp分析

    语句typedef int (*lpAddFun)(int ,int )定义了一个与add函数接收参数类型和返回值均相同的函数指针类型,随后在main函数中定义了lpAddFun的实例addFun;在函数main中定义了一个DLL HISTANCE句柄实例hDll,通过Win32API函数LoadLibrary动态加载DLL模块并将DLL模块句柄赋给hDll
    main函数中通过Win32API函数GetProcAddress得到所加载的DLL模块中函数add的地址并赋值给addFun,经由函数指针addFun进行了对该DLLadd函数的调用;
    在完成对dll的调用后,在main函数中通过Win32API函数FreeLibrary释放已加载的DLL模块。

    通过以上的分析可知:
    (a) 动态调用只需要dll文件即可,不需要对应的.h头文件和.lib文件,一般情况下,只要有dll,就可以调用此dll中的导出函数。
    (b) 在调用dll中的函数时,需要知道导出函数的函数签名,若拥有dll对应的头文件,可以参照头文件即可,若没有头文件,使用特定工具也可以得到dll中导出函数的函数签名
    (c) DLL需要已某种特定的方式声明导出函数。
    (d) 应用程序需要以特定的方式调用DLL的淡出函数。

    四、Visual Studio提供了一个命令行工具:Dumpbin

    这个工具不需要自己安装,我们通过安装VS,可以直接使用,如下打开VS自带的命令行工具,如下:
    在这里插入图片描述
    这个工具有什么作用呢?简而言之,它可以查看一个 lib文件 dll文件提供了哪一些函数,暴露出来可供使用的,它还可以查看 exe 文件包含了哪一些静态库和动态库。

    查看一下它的帮助信息:
    在这里插入图片描述

    如何使用呢?举几个简单的例子,以本文所创建的动态库和可执行程序作为演示:

    (1)查看Dll_demo_1.dll 暴露出来了哪一些函数可以使用——dumpbin -exports xxxx.dll(xxxx.lib文件也一样的)

    F:\OpenCV4.1.1_Test\2020_01_10\calcuDll\calculate\x64\Release>dumpbin -exports calculate.dll

    总结:

    查看导入:dumpbin -exports 文件名称

    查看导出:dumpbin -imports 文件名称


    1. https://blog.csdn.net/qq_33757398/article/details/81545966 ↩︎ ↩︎

    展开全文
  • Windows下使用静态库和动态库

    万次阅读 2016-05-10 23:26:39
    Windows下使用静态库和动态库

    Windows下使用静态库和动态库

    (一)环境

    Windows 7 32位
    Visual Studio 2013


    (二)dll和lib简介

    在Windows下很好理解这些概念,因为当你需要引入一个动态库(dll)或者一个静态库(lib)时一般的步骤是:

    添加头文件
    配置头文件目录
    配置库的目录
    将dll拷贝到可执行文件所在的目录(仅限于动态库)

    因此,就很好理解.h文件、.dll文件和.lib文件的关系:

    .h文件是编译时需要的,因为里面有函数或变量声明。
    .dll文件是生成的动态库,是在程序运行时动态加载的。
    而.lib文件就有话说了,首先,对于一个静态库来说,其是以xxx.lib的形式,而对于一个动态库来说,当IDE帮我们生成了.dll文件时,还会同时生成一个xxx.lib文件,这里的.lib不是静态库,而是动态链接库的导入库(Import Libary)


    (三)Windows下使用静态库

    生成静态库

    (1) 在VS2013中创建Win32项目,创建后编译器弹出选项框,选择静态库项目。

    这里写图片描述

    (2)分别编写.h文件和.cpp文件

    //StaticMath.h
    #pragma once
    class StaticMath
    {
    public:
        StaticMath(void);
        ~StaticMath(void);
        static double add(double a, double b);
        static double sub(double a, double b);
        static double mul(double a, double b);
        static double div(double a, double b);
    };
    //StaticMath.cpp
    #include "StaticMath.h"
    double StaticMath::add(double a, double b)
    {
        return a + b;
    }

    (3)右键项目->生成

    在项目的Debug目录下生成静态库。

    这里写图片描述

    使用静态库

    (1)创建控制台应用程序,并编写测试代码:**

    //testStatic.cpp
    #include <iostream>
    #include "StaticMath.h"
    int main()
    {
        double a = 1.2;
        double b = 2.4;
        std::cout << "a+b="<<StaticMath::add(a, b)<<std::endl;
        system("pause");
        return 0;
    }

    (2)配置项目

    配置头文件引用目录:项目属性->C/C++->常规->附加包含目录->静态库头文件所在的目录。

    这里写图片描述

    配置静态库的目录:项目属性->链接器->命令行->其它选项->添加静态库的绝对路径

    这里写图片描述

    (3)测试静态库

    直接编译运行测试项目,结果如下:

    这里写图片描述


    (四)Windows下使用动态库

    Windows下使用动态库就要比静态库复杂多了。

    创建动态库

    (1)在VS2013创建Win32项目,并选择动态库,这时系统会自动帮我们做一些事情:比如会写DLLMain函数作为初始化的入口、比如会初始化.h和.cpp文件,里面有示例导出函数和导出类声明。我们只需要在其基础上做一些补充即可:

    //DynamicMath.h
    // 下列 ifdef 块是创建使从 DLL 导出更简单的
    // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DYNAMICMATH_EXPORTS
    // 符号编译的。在使用此 DLL 的
    // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
    // DYNAMICMATH_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
    // 符号视为是被导出的。
    #ifdef DYNAMICMATH_EXPORTS
    
    #define DYNAMICMATH_API __declspec(dllexport)
    #else
    #define DYNAMICMATH_API __declspec(dllimport)
    #endif
    
    // 此类是从 DynamicMath.dll 导出的
    class DYNAMICMATH_API CDynamicMath {
    public:
        CDynamicMath(void);
    
        // TODO:  在此添加您的方法。
        static double add(double a, double b);
        static double sub(double a, double b);
        static double mul(double a, double b);
        static double div(double a, double b);
    };
    //示例导出变量声明
    extern DYNAMICMATH_API int nDynamicMath;
    //示例导出函数声明
    DYNAMICMATH_API int fnDynamicMath(void);

    这里编译器生成的模板中,CDynamicMath类已经被DYNAMICMATH_API(从DynamicMath.dll导出)修饰,因此类中的成员函数无需再用DYNAMICMATH_API修饰

    // DynamicMath.cpp : 定义 DLL 应用程序的导出函数。
    //
    
    #include "stdafx.h"
    #include "DynamicMath.h"
    
    
    // 这是导出变量的一个示例
    DYNAMICMATH_API int nDynamicMath=0;
    
    // 这是导出函数的一个示例。
    DYNAMICMATH_API int fnDynamicMath(void)
    {
        return 42;
    }
    
    // 这是已导出类的构造函数。
    // 有关类定义的信息,请参阅 DynamicMath.h
    CDynamicMath::CDynamicMath()
    {
        return;
    }
    
    //我自己添加的导出函数
    double CDynamicMath::add(double a, double b)
    {
        return a + b;
    }

    右键项目->生成将在debug目录下将生成:

    DynamicMath.dll(动态链接库)
    DynamicMath.lib(动态链接库的导入库)

    这里写图片描述

    有了.h文件 、动态链接库、导入库这三件套,我们就可以很容易的静态加载(即隐式链接的方式)动态链接库了。否则的话,就需要自己LoadLibrary调入DLL文件,再手动GetProcAddress获得对应函数了(又称显式链接)。

    下面是参考:http://blog.csdn.net/yusiguyuan/article/details/12649737 整理的一些资料。

    有了导入库,你只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。导入库和静态库的区别很大,他们实质是不一样的东西。静态库本身就包含了实际执行代码、符号表等等,而对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符号表等,确保程序找到对应函数的一些基本地址信息。

    一般的动态库程序有lib文件和dll文件。lib文件是必须在编译期就连接到应用程序中的,而dll文件是运行期才会被调用的。如果有dll文件,那么对应的lib文件一般是一些索引信息,具体的实现在dll文件中。如果只有lib文件,那么这个lib文件是静态编译出来的,索引和实现都在其中。静态编译的lib文件有好处:给用户安装时就不需要再挂动态库了。但也有缺点,就是导致应用程序比较大,而且失去了动态库的灵活性,在版本升级时,同时要发布新的应用程序才行。在动态库的情况下,有两个文件,而一个是引入库(.LIB)文件,一个是DLL文件,引入库文件包含被DLL导出的函数的名称和位置,DLL包含实际的函数和数据,应用程序使用LIB文件链接到所需要使用的DLL文件,库中的函数和数据并不复制到可执行文件中,因此在应用程序的可执行文件中,存放的不是被调用的函数代码,而是DLL中所要调用的函数的内存地址,这样当一个或多个应用程序运行是再把程序代码和被调用的函数代码链接起来,从而节省了内存资源。从上面的说明可以看出,DLL和.LIB文件必须随应用程序一起发行,否则应用程序将会产生错误。

    使用动态库

    这里使用隐式链接(静态加载)的方式。

    (1)创建控制台应用程序,并编写测试代码

    #include "DynamicMath.h"
    #include <iostream>
    int main()
    {
        int num = fnDynamicMath();//自动生成的示例导出函数
        std::cout << num << std::endl;
        double a=1.2;
        double b=2.5    ;
        std::cout << CDynamicMath::add(a, b) << std::endl;
        system("pause");
        return 0;
    }

    (2)配置项目

    配置头文件目录:项目属性->C/C++->常规->附加包含目录

    这里写图片描述

    配置导入库(附加依赖项)目录:项目属性->链接器->常规->附加库目录
    除此之外还需要配置具体附加依赖项.lib:配置属性->链接器->输入-> 在“附加依赖项”里添加“DynamicMath.lib”

    这里写图片描述

    这里写图片描述

    配置动态链接库目录:项目属性->配置属性->VC++目录->库目录

    这里写图片描述

    (3)测试

    编译运行测试动态库项目,发现错误:说系统找不到DynamicMath.dll文件,事实上,我们需要将dll文件拷贝到测试工程的Debug目录下后正常运行:

    这里写图片描述


    (五)参考

    http://www.cnblogs.com/houkai/archive/2013/06/05/3119513.html
    http://www.cnblogs.com/skynet/p/3372855.html
    http://blog.csdn.net/yusiguyuan/article/details/12649737
    http://blog.csdn.net/zhangxiao93/article/details/51344625

    展开全文
  • Windows动态库注册和取消注册

    千次阅读 2018-12-04 23:26:38
    Windows动态库的注册和取消注册 通过dos命令行注册和取消注册,注意cmd可能需要用管理员权限运行才能注册成功。   regsvr32命令用于注册COM组件,是Windows系统用来注册系统控件或卸载控件的命令。 ——百度...
  • Windows动态库和静态库的总结

    千次阅读 2016-01-24 00:29:35
    Windows下的动态库编程并不很熟悉。下午利用一点时间写了个原型,过程中想到许多问题,网上搜到许多文章,学到不少知识,但感觉比较繁杂,于是决定理一理,就有了这篇博文。
  • windows下应用程序加载动态链接路径依次分别是: 举例D盘soft文件夹下存在了一个test.exe的执行文件,即d:\soft\test.exe,依赖test.dll动态链接. ■程序的执行目录 test.exe执行文件存放在D盘下的soft文件平下,...
  • 为何Windows下的动态库总伴随一个静态库? 今天同学来问了一个问题:Visual Studio中生成的动态库总是伴随着一个静态库文件,我把这两个文件同样进行重命名之后还能不能使用? 我对VS下的动态库的生成并...
  • 最近使用QT编辑界面,需要用到QT调用动态库这部分功能。网上参考了许多帖子,完成了该部分功能,现将整体流程重新记录,以便大家参考。如有疑问,欢迎交流! 首先,使用VS生成一个动态库(具体如何生成,这里不做...
  • Linux动态库和静态库

    万次阅读 多人点赞 2021-10-28 10:56:35
    文章目录动静态库的基本原理认识动静态库动静态库各自的特征静态库的打包与使用打包使用动态库的打包与使用打包使用 动静态库的基本原理 动静态库的本质是可执行程序的“半成品”。 我们都知道,一堆源文件和...
  • 在项目中,需要对已有的动态库封装成JNI库,但在java程序测试中发现有某些动态库一直加载不成功,在网上通用的设置路径方法都试过了(包括/etc/ld.so.conf、LD_LIBRARY_PATH等等),还是不成功,最终在尝试了我能...
  • qt在Windows下调用动态库

    千次阅读 2016-05-26 13:13:18
    原来调用动态库采用先定义函数 typedef int(*funCD109_Init)(int); 再加载库的方式 QLibrary mylib1("TSCLib.dll"); //判断是否正确加载 if(mylib1.load()) { //调用外部函数 add() if(tscclearbuffer == N
  • Windows与Linux动态库的两种加载方式

    千次阅读 2016-11-25 17:35:56
    Windows上的动态库(dll)加载方式有两种: 1.静态加载,运用#pargma comment(lib, "xxx.dll")方式,这种方式需要 头文件,lib文件和dll文件配合使用,运行时是直接将动态库加载到内存中的,运用起来也比较方便 2.动态...
  • 1.在qtcreater中按如下步骤创建动态库动态库名为mydll: 选择Library项目,C++库 选择共享库: 选择qt自带的kit: 在工程中自动生成的mydll.pro文件里内容如下: #---------------------------------------...
  • 在资管监视器窗口中选择CPU标签页,在进程中找到你要查看的应用程序并勾选,然后打开关联的模块最右边的下拉箭头,即可查看到当前选择的应用程序调用的动态链接文件信息了! 可以选中任意一条动态链接文件...
  • windows 系统平台上,dll 动态库没有提供 .lib 文件,又不想动态获取函数地址怎么办? 使用 lib.exe 工具可以根据 .def 定义文件生成 .lib 文件。 例如,我这里有一个 test.dll 动态库文件,我想要生成 lib 链接...
  • Linux下动态库是.so文件。 Qt嵌套在visual studio时,编译器是MSVC,而Qt Creator的编译器是MinGW,针对MSVC和MinGW这两种编译器,作个简单的介绍: MSVC是指微软的VC编译器。 MinGW是指是Minimalist GNU on ...
  • Windows 系统自带的一个非常强大的工具,用于跟踪应用程序运行动态链接的加载情况。下面举一个案例,使用 sxstrace.exe 调试应用程序启动时抛出的"side-by-side"的加载异常。   在一台 WindowsServer 2008 R2 ...
  • windows和linux的动态库环境变量

    千次阅读 2017-07-13 18:10:46
    Windows程序在start时,同Linux一样,要将动态库load进来,Linux会查找LD_LIBRARY_PATH, Windows会查找环境变量PATH,以下是各平台的查找路径:    Linux: LD_LIBRARY_PATH  Solaris:LD_LIBRARY_PATH  HP: ...
  • windows动态库:xxx.dll2.3. linux的动态库:libxxx.so2.4. linux的静态库:xxx.a三. 自己编译库3.1 编译产生windows的静态库3.1.1代码准备:3.1.2 static_lib.cpp:3.1.3 static_lib.h:3.2 编译...
  • 2.创建新项目,选择C Library,库类型有两种,动态库选择shared,静态库的话选择static, 点击创建 3.创建之后默认会自动生成文件如下: 4.点击菜单上的“Build->Build Project”,可以看到生成了...
  • C/C++动态库加载

    千次阅读 2019-07-11 15:44:37
    C/C++动态库加载动态库动态库加载方式链接加载动态加载dlopendlsymdlclosedlerrorextern 'C'参考end 动态库 动态库又称动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用...
  • 这时需要查看可执行程序或者动态库中的符号表,动态库的依赖项, Linux 有现成的工具可用:objdump 。 objdump 是 gcc 套件中用来查看 ELF 文件的工具,具体详细用法不进行介绍,此处只讲解如何进行一个动态库和静态...
  • linux查看当前加载的所有动态库

    万次阅读 2017-07-27 14:35:08
    因为之前用的一个动态库现在要换一个版本,所以就想看一下这个库是否还在加载。 转自:http://blog.csdn.net/leo115/article/details/7773887 在我们做Linux开发的时候,往往会出现 某些库 can not ...
  • C++静态库与动态库的区别

    千次阅读 2019-08-31 16:11:52
    Windows下创建与使用动态库 动态库的显式调用 在Linux下显式调用动态库Windows下显式调用动态库 显式调用C++动态库注意点 附件:Linux下库相关命令 g++(gcc)编译选项 nm命令 ldd命令 总结 这次分享的 宗旨 是...
  • 在开发过程中,不知道如何去生成一个静态库或动态库,如何去使用静态库和动态库。 本文在讲述配置静态库和动态库的同时,会在工程中体现如何使用静态库和动态库。 需要下载工程的小伙伴请读到最后,有惊喜等着你。...
  • 如何查看一个运行的exe执行程序需要有哪些DLL动态链接第一步:打开“360安全卫士”软件笔者的360安全卫士的版本是:8.8第二步:打开“功能大全”菜单第三步:运行“360任务管理器”。 第四步:用鼠标选中查看需要...
  • 一、首先在Windows上进行封装: IDE是vs2017: 1、首先写好所需的头文件和源文件。接口定义在头文件中,对应的一个源文件是接口的实现。然后移除掉main.cpp. 2、然后添加def文件,是用来到处接口函数的。 ...
  • linux windows静态库和动态库的区别

    千次阅读 2012-01-17 16:45:04
    注意:Linux 静态编译时将动态库也编入文件中。 文件预览 文件目录树如下,如你所见,非常简单。  1. libtest/  2. |-- lt.c  3. |-- lt.h  4. `-- test.c 代码 #lt.c  1. /* lt.c  2. * ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 228,337
精华内容 91,334
关键字:

windows查看运行的动态库