c++ 动态链接库 资源文件_wsastartup函数头文件

c++ 动态链接库 资源文件_wsastartup函数头文件原创文章,转载请注明出处。C++Lib和Dll的加载加载Dll1>通过LoadLibary加载,GetProcAddress调用加载Dll1>通过LoadLibary加载,GetProcAddress调用如果加载失败,通过GetLastError()获取失败原因。下面是LoadLibary的示例代码第一步,在.h中声明了staticHMODULEhDLL;#include<Windows.h>//加载的头文件classQIDCardReader:.

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

原创文章,转载请注明出处。

如果Windows系统有缺失的DLL文件,可以去这个链接下载。点击去这里寻找

1>认识DLL(动态链接库)

动态链接库DLL(Dynamic-Link Library)通常包含程序员自定义的变量和函数, 可以在运行时动态链接到可执行文件(我们的exe程序)中。

2 >格式后缀

Windows上:(.dll)
Linux上:(.so)
Android上:(.so)
IOS上:(.dylib)

3 >DLL优点

1)模块化,耦合小:大规模软件开发中,开发过程独立,耦合度小,比如UE4里面的模块(每一个.build.cs)都是一个DLL。

2)扩展性:DLL文件与EXE文件是独立的,只要接口不变,升级程序只需更新DLL文件不需要重新编译应用程序。并且我们的EXE文件较小。

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

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

5)隐私性:可以当做黑盒使用,可以将我们的具体实现代码隐藏起来,比如我们想将算法的具体实现隐藏起来,不让别人看到我是怎么做的。一般SDK接入时候,里面的具体算法实现都是不会公开cpp的。

4 >DLL缺点

如果是动态loaddll的话,会牺牲部分性能吧。微乎其微的。

5 >加载DLL

1>动态加载(运行时加载)通过LoadLibary加载, GetProcAddress调用。

如果加载失败,通过GetLastError()获取失败原因。

下面是LoadLibary的示例代码
第一步,在.h中声明了static HMODULE hDLL;

#include<Windows.h> //加载的头文件

class QIDCardReader : public QMainWindow
{ 
   
    Q_OBJECT

public:
    QIDCardReader(QWidget* parent = 0);
private:
	static HMODULE hDLL;
};

第二步,定义要调用的dll中的方法。并通过LoadLibrary给hDLL赋值

#include "QIDCardReader.h"

//CPP中预声明一下我要调用dll里面的方法
typedef int(*MyRouton_RepeatRead)(bool);
typedef int(*MyInitComm)(int);
typedef int(*MyAuthenticate)();
typedef int(*MyReadBaseInfosPhoto)(char * , char * , char * ,
	char *, char * , char * ,
	char *, char * , char* , char * );
typedef int(*MyCloseComm)();

HMODULE QIDCardReader::hDLL;

QIDCardReader::QIDCardReader(QWidget* parent) : QMainWindow(parent)
	,ui_(new Ui::QIDCardReaderClass)
{ 
   
	hDLL = LoadLibrary(L"D:\\bimvr-vrlauncher\\test\\Sdtapi.dll"); //加载dll文件 
	//如果加载失败的话, 通过GetLastError()进行获取,看失败原因。
	auto code5 = GetLastError();
}

第三步,调用dll中的方法 GetProcAddress(hDLL, “实际的dll端函数导出名称”)

//调用1
if (hDLL)
{ 
   
	MyRouton_RepeatRead MyRouton_RepeatReadFunc = (MyRouton_RepeatRead)GetProcAddress(hDLL, ("Routon_RepeatRead"));//直接使用原工程函数名 
	if (MyRouton_RepeatReadFunc)
	{ 
   
		MyRouton_RepeatReadFunc(true);
	}

}

//调用2
int iPort = 1001;
//int ret = InitComm(iPort);
int ret = -1000;
if (hDLL)
{ 
   
	MyInitComm MyInitCommFunc = (MyInitComm)GetProcAddress(hDLL, ("InitComm"));//直接使用原工程函数名 
	if (MyInitCommFunc)
	{ 
   
		ret = MyInitCommFunc(iPort);
	}
}
if (ret)
{ 
   
	//ret = Authenticate();
	if (hDLL)
	{ 
   
		MyAuthenticate MyAuthenticateFunc = (MyAuthenticate)GetProcAddress(hDLL, ("Authenticate"));//直接使用原工程函数名 
		if (MyAuthenticateFunc)
		{ 
   
			ret = MyAuthenticateFunc();
		}
	}
	if (ret)
	{ 
   
		char user_name[31] = { 
    0 };
		char user_gender[3] = { 
    0 };
		char user_folk[11] = { 
    0 };
		char user_birthday[9] = { 
    0 };
		char user_code[19] = { 
    0 };
		char user_address[71] = { 
    0 };
		char user_agency[31] = { 
    0 };
		char expire_start[9] = { 
    0 };
		char expire_end[9] = { 
    0 };

		QByteArray data_path = QString::fromStdWString(AppUtils::GetDataPath()).toLatin1();
		ret = ReadBaseInfosPhoto(user_name, user_gender, user_folk, user_birthday, user_code,
			user_address, user_agency, expire_start, expire_end, str/*data_path.data()*/);
		if (hDLL)
		{ 
   
			MyReadBaseInfosPhoto MyReadBaseInfosPhotoFunc = (MyReadBaseInfosPhoto)GetProcAddress(hDLL, ("ReadBaseInfosPhoto"));//直接使用原工程函数名 
			if (MyReadBaseInfosPhotoFunc)
			{ 
   
				ret = MyReadBaseInfosPhotoFunc(user_name, user_gender, user_folk, user_birthday, user_code,
						user_address, user_agency, expire_start, expire_end, str/*data_path.data()*/);
			}
		}
	}
}

第四步,可以选择性调用FreeLibrary(hDLL)卸载Dll,这个是下面的静态三件套加载方式做不到的。
也就是说我们可以动态控制Dll的加载与卸载。

2>静态加载方式(.h .lib .dll三件套加载)

1>项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件Sdtapi.h所在的目录
2>项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件Sdtapi.lib所在的目录
3>项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“Sdtapi.lib”(若有多个 lib 则以空格隔开)
也可以使用#pragma comment(lib, “Sdtapi.lib”)代替上面的1、2、3步骤。

在这里插入图片描述
QIDCardReader.cpp 包含.h,将.h添加到项目中

#include "sdtapi.h"

void QIDCardReader::onNotify()
{ 
   
	Routon_RepeatRead(true);

	int iPort = 1001;
	int ret = InitComm(iPort);
	if (ret)
	{ 
   
		ret = Authenticate();
		if (ret)
		{ 
   
			char user_name[31] = { 
   0};
			char user_gender[3] = { 
   0};
			char user_folk[11] = { 
   0};
			char user_birthday[9] = { 
   0};
			char user_code[19] = { 
   0};
			char user_address[71] = { 
   0};
			char user_agency[31] = { 
   0};
			char expire_start[9] = { 
   0};
			char expire_end[9] = { 
   0};

			QByteArray data_path = QString::fromStdWString(AppUtils::GetDataPath()).toLatin1();
			ret = ReadBaseInfosPhoto(user_name, user_gender, user_folk, user_birthday, user_code,
				user_address, user_agency, expire_start, expire_end, data_path.data());
		}
	}
}

现在是可以通过编译了,但是运行会报错 提示LinkError
因为程序分为编译和链接两步骤,这就是为什么报错误的原因。
我们解决这个报错就是将.dll放到和.exe同级目录就好了

如果最终exe找不到dll的话,会提示下面的错误。解决方法就是将dll放到和exe同级目录就好了。
在这里插入图片描述
谢谢,创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 <( ̄︶ ̄)>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187575.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 在vscode中安装python第三方库

    在vscode中安装python第三方库打开vscode,点击终端,选择新建终端在弹出的窗口中输入以下命令:pipinstall第三方库的名称以安装numpy为例,输入pipinstallnumpy,点击回车,安装成功之后会显示如下信息:Requirementalreadysatisfied:numpyind:\python\lib\site-packages(1.20.3)已经满足的需求:numpy在d:python\lib\site-packages(1.20.3)…

    2022年10月7日
    0
  • java list三种遍历方法性能比較

    java list三种遍历方法性能比較

    2021年9月1日
    55
  • stm32 spi协议_STM32库开发实战指南:基于STM32F4

    stm32 spi协议_STM32库开发实战指南:基于STM32F4深入讲解SPI协议通信时序,详细解析SPI读写串行FALSH实验,NorFlash的存储特性以及读写指令的详细介绍!!!

    2022年10月15日
    0
  • navicat注册码最新_navicat激活工具

    navicat注册码最新_navicat激活工具navicat10.1.7版本,亲测可用。名:NAVN-LNXG-XHHX-5NOO组织:NAVN-LNXG-XHHX-5NOO注册码:NAVN-LNXG-XHHX-5NOO

    2022年10月13日
    0
  • C# ACCESS数据库操作类

    这个是针对ACCESS数据库操作的类,同样也是从SQLHELPER提取而来,分页程序的调用可以参考MSSQL那个类的调用,差不多的,只是提取所有记录的数量的时候有多一个参数,这个需要注意一下!推荐:

    2021年12月27日
    37
  • 非局部均值滤波算法[通俗易懂]

    非局部均值滤波算法[通俗易懂]2016.09.09更新,修改了SSIM中值太大的问题首先谈一下什么是非局部均值滤波。在此之前,我们先来看一下均值滤波的原理。均值滤波均值滤波的计算非常简单,将图像像素点灰度记录在数组中,然后设置方框半径的值,然后将方框中的所有点的像素求和取平均,得到的结果就是均值滤波后对应像素点的灰度值。优点:计算很快而且简单从算法可以看出,只是求了平均,并没有很复杂的计算缺点:得到的图像很模

    2022年5月21日
    45

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号