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)
blank

相关推荐

  • afl-fuzz技术白皮书[通俗易懂]

    afl-fuzz技术白皮书[通俗易懂]通过在编译期间instrument一些指令来捕获branch(edge)coverage和运行时分支执行计数。

    2022年10月21日
  • document.querySelector()方法[通俗易懂]

    document.querySelector()方法[通俗易懂]HTML的DOMquerySelector()方法可以不需要额外的jQuery等支持,也可以方便的获取DOM元素,语法跟jQuery类似。获取文档中id=”container”的元素&lt;!DOCTYPEhtml&gt;&lt;htmllang="en"&gt;&lt;head&gt;&lt;metacharset="UTF-8"&gt;&lt;ti

  • Yii 多語言

    Yii 多語言

  • 锂电池稳压3.3V芯片_电源芯片型号

    锂电池稳压3.3V芯片_电源芯片型号干电池升压3.3V的电源芯片PW5100适用于一节干电池升压到3.3V,两节干电池升压3.3V的升压电路,PW5100干电池升压IC。干电池1.5V和两节干电池3V升压到3.3V的测试数据输入电压输入电流输出电压输出电流0.9V输入测试0.907V0.21A3.26V50MA0.887V0.45A3.21V100MA0.857V0.83A3.12V150MA输入电压输入电流输出电压输出电流1V输入测试1V0.9…

  • 安装maven及查看maven版本号

    1、从Apache官网下载maven的压缩包,目前最新的是apache-maven-3.6.0网站地址:http://maven.apache.org/2、解压到非中文目录即可在conf文件夹下的settings.xml是maven默认的配置,一般会修改maven的默认配置文件2.1、修改本地仓库的存放位置<!–本地仓库地址–><localRepos…

  • jsp延时跳转_js自动跳转到指定页面

    jsp延时跳转_js自动跳转到指定页面本文仅供学习交流使用,如侵立删!联系方式及demo下载见文末js延时页面跳转<scripttype=”text/javascript”> functionsend(){ alert(“转账码制作成功!!!”); window.history.back();//返回上一页 } setTimeout(send,2000);//等待2秒后执行</script>本文仅供学习交流使用,如侵立删!企鹅、WX:1033383881…

发表回复

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

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