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同级目录就好了。
在这里插入图片描述
谢谢,创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 <( ̄︶ ̄)>

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 带通滤波器幅频特性曲线图_滤波器知识,你所要的,都在这里

    带通滤波器幅频特性曲线图_滤波器知识,你所要的,都在这里滤波器是一种选频装置,可以使信号中特定的频率成分通过,而极大地衰减其它频率成分。一、概述1、定义凡是可以使信号中特定的频率成分通过,而极大地衰减或抑制其他频率成分的装置或系统都称之为滤波器,相当于频率“筛子”。2、分类频率通带:能通过滤波器的频率范围。频率阻带:被滤波器抑制或极大地衰减的信号频率范围。截止频率:通带与阻带的交界点。2)按物理原理分:机械式、电路式;按处理信号分:模拟、数字3、滤波…

  • 什么是PMF?

    什么是PMF?PMF是ProductMarketFit的简写,是指产品和市场达到最佳的契合点,你所提供的产品正好满足市场的需求,令客户满意,这是创业成功的第一步。PMF如何实现PMF金字塔模型PMF金字塔模型“PMF金字塔模型”是一个可操作的模型,它用5个关键要素定义了PMF的问题。在这个层级模型中,每一个要素就是金字塔的一层,并且直接与它上下层相关联。从下到上,这5层依次是:你的目标用户,你用户未被满足的需求,你的价值主张,产品的功能集,你的用户体验(UX)。精益产品开发流程是建立在P.

  • 一个简单的ETL开发的过程(informatica)

    一个简单的ETL开发的过程(informatica)大致的了解过程,中间不涉及组件部分。 正文PowerCenter的开发过程大致可以分为几步:1.在客户端PowerCenterDesigner中导入源表和目标表的结构定义。(只是表结构)2.在PowerCenterDesigner中执行的事件为:   1&gt;.创建Mapping。   2&gt;.拖动源和目标进入Mapping。(类似于定义变量)   …

  • RabbitMQ入门:总结

    随着上一篇博文的发布,RabbitMQ的基础内容我也学习完了,RabbitMQ入门系列的博客跟着收官了,以后有机会的话再写一些在实战中的应用分享,多谢大家一直以来的支持和认可。RabbitMQ入门系

  • csgo绑定一键跳投创意工坊(csgo取消一键跳投)

    此篇文章我写出三种方法本人最推荐第三种!!!方法一废话从不多说直接在电脑上新建一个记事本命名随意(我的命名为1)在记事本里面直接粘贴以下代码alias+jumpthrow”+jump;-attack”alias-jumpthrow”-jump”bindN+jumpthrow(N为所绑定的按键为了醒目我加的粗可以随意更改)如图所示录入后记得保存然后在游戏中打开控制台一般是~键然…

  • Eclipse快捷键大全

    Eclipse快捷键大全

发表回复

您的电子邮箱地址不会被公开。

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