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)
上一篇 2022年9月30日 上午9:16
下一篇 2022年9月30日 上午9:16


相关推荐

  • java实现第三方微信登录

    java实现第三方微信登录使用微信进行第三方登录总共分为三步 1 获取 code1 首先展示二维码 让用户进行扫描授权两种方式 直接使用 a 标签进行链接二维码我们要填写的信息有 appId 微信开发平台创建应用后提供 redirect uri 回调域名 必须是开发平台的创建应用的回调域名之下 state 唯一凭证 随便填 请求路径 需更改

    2026年3月17日
    2
  • 史上最全的SpringMVC学习笔记

    史上最全的SpringMVC学习笔记

    2022年3月2日
    64
  • 常见免费API接口[通俗易懂]

    常见免费API接口[通俗易懂]https://www.apishop.net/#/api/detail/?productID=215

    2022年8月3日
    6
  • Python爬取网页数据

    Python爬取网页数据都说 python 爬网页数据方便 我们今天就来试试 python 爬取数据到底有多方便简介爬取数据 基本都是通过网页的 URL 得到这个网页的源代码 根据源代码筛选出需要的信息准备 IDE pyCharm 库 requests lxml 大概介绍一下 这俩库主要为我们做什么服务的 requests 获取网页源代码 lxml 得到网页源代码中的指定数据言简意赅有没有

    2026年3月19日
    2
  • k8s的apiserver_kube_apiserver

    k8s的apiserver_kube_apiserverAPIserverfunc main() { … #核心 command := app.NewAPIServerCommand() #日志 logs.InitLogs() defer logs.FlushLogs() …}#NewAPIServerCommand#核心是调用run函数 运行AIPserver 永远不会退出return Run(completedOptions, genericapiserver.SetupSignalHandler())#Run#创建

    2022年8月9日
    8
  • salt的grains工具和pillar工具使用详解

    salt的grains工具和pillar工具使用详解什么是 grains 工具 Salt 附带一接口 用于获取有关底层系统的信息 Salt 的 grains 主要存储静态数据 用来收集 minion 端的一些数据 比如 操作系统 域名 IP 地址 内核 操作系统类型 内存或者其他系统属性 Minion 端在启动时会读取 grains 数据 如果有新的 grains 数据需要重启 minion 服务或者在 master 端使用 salt 命令进行刷新一 minion 端的 roles 之前

    2025年8月11日
    10

发表回复

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

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