vs2015第一次生成dll库所遇到的问题

由于是第一次生成dll库,先普及一下dll库和lib库之间的联系和区别:
http://www.cnblogs.com/TenosDoIt/p/3203137.html 这篇博客将其解释的已经非常好了,截取出来以作记录。
首先两者都是代码共享的方式。
静态库:在链接步骤中,连接器将从库文件取得所需的代码,复制到生成的可执行文件中,这种库称为静态库,其特点是可执行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令都全部被直接包含在最终生成的 EXE 文件中了 。在vs中新建生成静态库的工程,编译生成成功后,只产生一个.lib文件
动态库:动态链接库是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可执行文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。 在vs中新建生成动态库的工程,编译成功后,产生一个.lib文件和一个.dll文件
那么上述静态库和动态库中的lib有什么区别呢?
静态库中的lib:该LIB包含函数代码本身(即包括函数的索引,也包括实现),在编译时直接将代码加入程序当中
动态库中的lib:该LIB包含了函数所在的DLL文件和文件中函数位置的信息(索引),函数实现代码由运行时加载在进程空间中的DLL提供

总之,lib是编译时用到的,dll是运行时用到的。如果要完成源代码的编译,只需要lib;如果要使动态链接的程序运行起来,只需要dll。

开始对于编译dll库有个困惑,即若我封装的函数中含有第三方库(如opencv或ffmpeg),能够生成dll吗?如果能,那么会有什么影响?
答案肯定是可以生成dll的,比如ffmepg的库就是包含了很多第三方库(如x264等各类编码器库),至于会有什么影响,主要是在调用的时候会有一定影响,需要配置你所用到的第三方库的头文件、dll库和lib库;

那么可以开始编译了,代码如下:

THapi.h中代码
#pragma once
#include "param.h"
#include "ThreadProcess.h"
extern  int THfun(void);
THapi.app中代码
#include "THapi.h"  
using namespace std;
using namespace cv;

#ifdef _DEBUG
#pragma comment(lib,"opencv_world320d.lib")
#else
#pragma comment(lib,"opencv_world320.lib")
#endif

int THfun(void)
{
	HANDLE hThreadStudent;
	unsigned   threadIDStudent;

	// 创建互斥对象
	hMutex_techer = CreateMutex(NULL, FALSE, NULL);

	initProjectParam();
	// 创建线程
	hThreadStudent = (HANDLE)_beginthreadex(NULL, 0, StudentProc, NULL, 0, &threadIDStudent); // 创建子线程并立即执行,其中StudentProc函数在另个文件中,暂不展示了
	WaitForSingleObject(hThreadStudent, INFINITE); //等待子线程执行完毕

	//一定要记得关闭线程句柄
	CloseHandle(hThreadStudent);
	getchar();

	return 0;
}
编译完成,兴奋的去文件夹中查看生成的dll文件和lib文件,发现只生成了dll文件而没有生成lib文件,经查发现了“__declspec(dllexport)”的重要性,加上此语句编译器才知道你需要将此函数连接到lib文件,于是对上述代码进行修改,如下

THapi.h中代码
#pragma once
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
#include "param.h"
#include "ThreadProcess.h"
extern "C" DLL_API int THfun(void);

THapi.app中代码
#include "THapi.h"  
using namespace std;
using namespace cv;

#ifdef _DEBUG
#pragma comment(lib,"opencv_world320d.lib")
#else
#pragma comment(lib,"opencv_world320.lib")
#endif

int THfun(void)
{
	HANDLE hThreadStudent;
	unsigned   threadIDStudent;

	// 创建互斥对象
	hMutex_techer = CreateMutex(NULL, FALSE, NULL);

	initProjectParam();
	// 创建线程
	hThreadStudent = (HANDLE)_beginthreadex(NULL, 0, StudentProc, NULL, 0, &threadIDStudent); // 创建子线程并立即执行,其中StudentProc函数在另个文件中,暂不展示了
	WaitForSingleObject(hThreadStudent, INFINITE); //等待子线程执行完毕

	//一定要记得关闭线程句柄
	CloseHandle(hThreadStudent);
	getchar();

	return 0;
}
果然经过修改之后,最终生成了dll文件和lib文件

下面对其进行调用,验证其生成是否正确?
代码如下:
#include "THapi.h" 

#pragma comment(lib,"mylib.lib")
#ifdef _DEBUG
#pragma comment(lib,"opencv_world320d.lib")
#else
#pragma comment(lib,"opencv_world320.lib")
#endif

int main()
{
	THfun();
	return 0;
}

最终程序成功运行,验证成功。

需要再次提醒一下,由于我用到了第三方库即opencv,所以除了要配置好自己的lib库和dll库之外,还要配置好opencv的头文件以及库文件,除此之外需要将opencv的相关dll文件拷贝到程序运行目录,否则无法运行程序。






猜你喜欢

转载自blog.csdn.net/lifei092/article/details/79630273