您现在的位置是:首页» windows系统» 在visual studio中使用qt,如何用visualc++运行

在visual studio中使用qt,如何用visualc++运行

2024-07-12 20:51:02
本内容由系统网小编为大家分享,Windows系统安装教程、办公系统、软件怎么使用、软件使用教程、办公软件攻略等信息。"DLL"到底是什么? DLL 是多个应用程序可以同时使用的代码和数据的存储库。 例如,在 Windows 操作系统中, C

本内容由系统网小编为大家分享,Windows系统安装教程、办公系统、软件怎么使用、软件使用教程、办公软件攻略等信息。

"DLL"到底是什么?

DLL 是多个应用程序可以同时使用的代码和数据的存储库。 例如,在 Windows 操作系统中, Comdlg32 DLL 执行与对话框连接的共同操作。 因此, 每个应用程序都可以使用 DLL 中包含的功能完成 Open 对话框。 这将允许有效使用代码的重新使用和内存 。

你为什么雇用DLL?

一般而言,只要守则的一部分是通用的,它就可能被创建成一个合理独立的功能模块,并在以后的项目中重新使用。 更受欢迎的例子是应用框架,它以源代码的形式被公诸于世。 由于这种再利用处于源代码一级,源代码完全可供程序员使用,因此被称为“白代码”。

接触源代码,多份,导致储存废物; (b) 容易与程序员的当地代码相矛盾; (b) 改变模块功能的复杂性不利于问题模块化。

为解决这些缺陷,提出了“二进制”再利用代码。 在某种程度上,源代码被隐藏在代码再利用的二进制层面,不仅来自DLL,而且还来自静态链接库和更为复杂的COM组件。

以下是使用DLL的主要好处:

使用较少的资源; 当许多应用程序使用相同的功能库时, DLL 最大限度地减少存储在磁盘和物理内存上的代码重复数。 这不仅对前台应用程序,而且对 Windows 操作系统上运行的其他程序都有重大影响。 鼓励模块架构; 简化部署与安装。

创建DLL

为了绘制以下图表,打开2012年视觉工作室项目:

键入项目名称并按 [OK];

要完成此工程, 请单击 [ 完成] 。 现在我们可以添加我们的代码。 Join MyCode. H 和 MyCode. cpp 2 文件; 在 MyCode. 在 h 中输入以下代码 :

[cpp]  view plain  copy #ifndef _MYCODE_H_ #define _MYCODE_H_ #ifdef DLLDEMO1_EXPORTS #define EXPORTS_DEMO _declspec( dllexport ) #else #define EXPORTS_DEMO _declspec(dllimport) #endif extern "C" EXPORTS_DEMO int Add (int a , int b); #endif 在 MyCode 的 cpp 中插入以下代码 :[cpp]  view plain  copy #include "stdafx.h" #include "MyCode.h" int Add ( int a , int b ) { return ( a + b ); } 汇编项目将创建 DLDmo1. dll 文件。 代码中有很多信息, 我稍后将详细讨论这些信息 。

使用DLL

当我们的软件需要使用 DLL 时, 它必须装入它。 在程序内装入 DLL 有两种方式: 装入时的动态链接和运行时的动态链接 。

当装入动态链接时, 程序将导出 DLL 函数调用为本地函数 。 要在装入过程中使用动态链接, 在建立和连接应用程序时, 您必须提供主文件并导入图书馆文件 。 (.. 当动态链接在运行时,程序运行负载Library 或装入LibraryEx 函数以装入 DLL。在成功装入 DLL 后,您可以使用 GetProcAddress 方法获取导出 DLL 函数的地址。在使用运行中的动态链接时,您不需要使用导入库文件。

在实际方案拟订中应使用两种使用DLDD的技术中的哪一种?在实际发展过程中考虑到以下几个方面:

如果应用程序初始启动性能至关重要,应在运行时使用动态连接。 装入动态链接后,导出 DLL 函数与本地函数相似,随时可以调用; 随着程序运行,逻辑是动态连接的,应用程序可以分割,以便根据需要装入不同的模块。

然后,DLL动态链接库将以两种不同的方式使用。

加载时动态链接:

[cpp]  view plain  copy #include <windows.h> #include <iostream> //#include "..\DLLDemo1\MyCode.h" using namespace std; #pragma comment(lib, "..\debug\DLLDemo1.lib") extern "C" _declspec(dllimport) int Add(int a, int b); int main(int argc, char *argv[]) { cout<<Add(2, 3)<<endl; return 0; } 运行时动态链接:[cpp]  view plain  copy #include <windows.h> #include <iostream> using namespace std; typedef int (*AddFunc)(int a, int b); int main(int argc, char *argv[]) { HMODULE hDll = LoadLibrary("DLLDemo1.dll"); if (hDll != NULL) { AddFunc add = (AddFunc)GetProcAddress(hDll, "Add"); if (add != NULL) { cout<<add(2, 3)<<endl; } FreeLibrary(hDll); } }

所有代码都可以在 DLDmo1 项目中找到。 (项目下载)。

DllMain函数

当装入 DLL 时, Windows 需要一个入口函数, 类似于控制平台程序需要一个主要函数。 在某些情况下, DLL 不提供 DllMain 函数, 应用程序可以成功引用 DLL 函数, 因为 Windows 在无法找到 DllMain 时会从另一个操作库引入默认 DllMain 函数版本, 这并未表明 DLL 可以丢弃 DllMain 函数 。

根据写法标准, Windows 必须确定并运行 DLL 中的 DllMain 函数作为装入 DL 的基础, 使 DL 留在记忆中。 此函数不是一个导出函数, 而是一个内部 DLL 函数, 这意味着 DllMain 函数无法直接访问客户端, 并且自动调用 。

DllMain 函数在 DLL 装入和卸载时被调用, 当单线开始和停止时也被调用。 参数 ul_ reason_ for_ call 确定了调用 DllMain 的原因, 以下四个案例为:

DLL_ process_ ATTACH: 当 DLLS 初始装入进程地址空间时, 系统会调用 DLL 的 DllMain 函数, 并将 ul_ reason_ for_ call 参数值发送到 DLL_ PROCESS_ ATTACH 。

当进程启动新线索时, 系统将查看进程地址空间中所有 DLL 文件的地图, 然后使用 DLL_ TREAD_ ATTACH 调用 DLL 中的 DllMain 方法。 注意系统没有使用 DLL_ THEAD_ ATTACH 来调用 DLL 中的 DllMain 函数;

DLL_ process_ DETACH : 当从进程地址空间 DLL 映射 DLL 时, 参数 ul_ reason_ for_call 参数值为 DLL_ process_ DETACH 。 当 DLL 处理 DLL_ pROCESS_ DETACH 时, DLL 应该处理与进程有关的清理操作。 如果进程终止, 将会注意系统中有线条使用 TerrateProcess 完成, 系统将不会使用 DLL_ PROCES_DETACH 。

DLL_ TrEAD_ DETACH : 通知通知所有 DLL 有关线条清理的 DLL 。 请注意, 如果线索使用 ternateTread 终止, 系统将不使用 DLL_ Tread_ DETACH 来进行线索清理, 这可能导致数据丢失, 所以不使用 TernateTread 完成线索。 前面的所有解释都在 DLLMAINDemo 项目( 工程) 中表示 。

函数导出方式

在创建DLL时,我使用了这种输出功能的方法,然而,通过使用出口档案,有另一种方式可以输出功能。 Dev档案载有链接方案出口、属性和其他特点的信息链接。

在前一例子中,辩护可以是:

[cpp]  view plain  copy LIBRARY     "DLLDemo2" EXPORTS Add @ 1 ;Export the Add function

模块- 定义文件 (. 文档的( def) 格式如下 :

与 Dev 文件对应的 DLL 在库语句中提及 。 是的, dev 文件中的导出函数名称附在@n 上,这表明要导出函数的序列号为 n(此序列号在调用函数时有效)。

DLL 是使用 dev 文件创建的, 客户端执行以下代码 :

[cpp]  view plain  copy #include <windows.h> #include <iostream> using namespace std; typedef int (*AddFunc)(int a, int b); int main(int argc, char *argv[]) { HMODULE hDll = LoadLibrary("DLLDemo2.dll"); if (hDll != NULL) { AddFunc add = (AddFunc)GetProcAddress(hDll, MAKEINTRESOURCE(1)); if (add != NULL) { cout<<add(2, 3)<<endl; } FreeLibrary(hDll); } } 正如可以观察到的那样,传给 GetProctress 函数的第二个参数是 MaINTERSOURCE(1),它持有dev 文件中相应函数的序列号。 (项目下载)

extern “C”

为什么使用外部“ C ”? 因为当时已经存在大量的 C 代码, C++ 的父亲希望尽可能支持 C C 的 C++, 以便支持原 C 代码和已建 C 库, 这是其中一项技术。 在描述此功能时, 人们注意到我还使用了此处指定的外部“ C ” 。

外部“ C” 有两个含义: 首先, 它被定性为“ 外部 ”, 其次, 它被定性为“ C ” 。 在 C/ C++ 中, 用于指定函数和变量范围( 可见度) 的关键词通知汇编器, 指定函数和变量可以用于此模块或其他模块 。

如果在文档开头未声明外部变量,则其有效性仅限于从定义到文档结束的期间。如果在声明该变量之前需要提及该变量,则使用关键词“外部”将变量声明为外部变量,表明该变量是一个定义的外部变量。 [cpp]  view plain  copy /* ** FileName     : Extern Demo ** Author       : Jelly Young ** Date         : 2013/11/18 ** Description  : More information, please go to http://www.jellythink.com */ #include <iostream> using namespace std; int main(int argc, char *argv[]) { extern int a; cout<<a<<endl; } int a = 100; 在多文件程序中,如果多个文件要使用同一个外部变量,则无法在每份文件中定义每个外部变量,否则“定义的重复”就会有错误。 正确的做法是在任何一份文件中定义外部变量,而其他文件则使用外部变量来“减少外部变量”。 在汇编和链接时,系统将知道该变量是已在其他地方定义的外部变量,并将外部变量的使用领域扩大到另一个文件中的这一文档中,以便外部变量能够合法地在本文件中使用。 那些已经写入 MFC 程序的人知道,在 CXXApp 类标题中,使用外部变量来宣布该类别的变量,而该变量的实际定义在CXXApp 类实现文件中已经完成; 当定义函数时,在左端添加一个密钥,表示它是一个外部函数。Language C允许在定义时一个超人缺席时显示一个外部函数。内部函数必须有一个状态密钥。在要求调用此函数的文件中,使用外部实习生来声明该函数,表明该函数是另一个文件中创建的外部函数。

下一步是“ C” 定义 。 我们都知道 C++ 通过各种功能参数支持重负机制, 而编译器根据参数为每个重函数生成不同的内部识别符号; 但是, 如果 C++ 程序遇到调用已编译函数 C 的调用, 那么应该怎么做? 例如, Int Add (int a, int b) 函数 。 此函数在 C 编译器之后在库中被称为 _ Add_ int_int), 而 C++ 编译器生成了诸如 _ ad_ ad_int_int 等名称, 来支持重加载功能和类型安全 。 由于 C++ 程序无法直接调用所编译的不同名称的 C 函数; 但是, C++ 提供与指定符号Extern " C" 的 C 连接交换, 以解决此问题 。 因此, 在 DLL 上, 添加函数的语句格式是: Extern "C" Exports "Exports " Exports'Exports' Exports a, in the Dpent. LLW.

值得指出的是,出口方法为C++,出口的 Add 函数名称增加相当多。 以这种方式出口时, 当客户点调用时代码如下: [cpp]  view plain  copy #include <windows.h> #include <iostream> using namespace std; typedef int (*AddFunc)(int a, int b); int main(int argc, char *argv[]) { HMODULE hDll = LoadLibrary("DLLDemo1.dll"); if (hDll != NULL) { AddFunc add = (AddFunc)GetProcAddress(hDll, "?Add@@YAHHH@Z"); if (add != NULL) { cout<<add(2, 3)<<endl; } FreeLibrary(hDll); } }

请注意 GetProcAddress 方法的第二个参数, 即导出函数名称 。 当编码时写入此名称是否奇怪? 当我们使用外加的“ C” 方法导出时, 屏幕截图如下 :

导出模式现在是 C, 函数名称是标准添加 。 当我们使用 GetProcAddress 时, 我们可以直接识别添加, 而不是添加长长的奇名列表 。

DLL导出变量

调用过程可以访问 DLL 所宣布的全球变量,调用过程也可以访问调用过程的全球数据。

DLL导出类

DLL中描述的类别也可以导出。关于项目代码的更多信息,请参见(项目下载)。

总结

这结束了DLL的介绍,此处没有详细介绍,因为MFCs在当前环境中使用较少,我将总结一下,如果其他项目需要MFC DLL知识,我将总结一下。 最后,我想请您向我的博客提供一些相关建议。

本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。如果这篇文章对你有帮助,你可以请我喝杯咖啡。» 本文链接:http://www.jellythink.com/archives/111» 订阅本站:http://www.jellythink.com/feed » 转载请注明来源:果冻想 » <a rel="bookmark" title="在Visual Studio中使用C++创建和使用DLL"《在Visual Studio中使用C++创建和使用DLL》

******************************************************************************************************

鉴于上述情况,我在VS2010发展环境中进行了以下测试:

一. 封存必要的 DLL 功能。

第一个DLL项目题为DllDemo,内容如下: 然后创建页眉文件( MyCode) (MyCode) 。 (h) 和. Cpp 文件 (MyCode) 。 (cpp) 并插入以下代码: MyCode. hhead 文件: [cpp] 显示普通副本 #ifndef _MYCODE_H_ #define _MYCODE_H_ #ifdef DLLDEMO1_EXPORTS #define EXPORTS_DEMO _declspec( dllexport ) #else #define EXPORTS_DEMO _declspec(dllimport) #endif extern "C" EXPORTS_DEMO int Add (int a , int b); #endif [cpp] 显示 MyCode. cpp 的普通副本 #include "MyCode.h" int Add ( int a , int b ) { return ( a + b ); } DllDemo 将在 Debug 文件. dll 文件下由汇编工程生成 。

2。 当动态链接装入时, 它会称为 DLL 。

首先,如下图所示,建造一个称为DllTesto的控制应用程序: 并添加以下代码: [cpp] 查看纯复制 /DllTest.cpp: 此文件指定控制平台程序的切入点 。 #include "stdafx.h" #include <iostream> //#include "..\DLLDemo1\MyCode.h" using namespace std; ** extern "C" _declspec(dllimport) int Add(int a, int b); int _tmain(int argc, _TCHAR* argv[]) { cout<<Add(2, 3)<<endl; (1) / 本程序在此执行, 以方便显示操作结果 return 0; } 运行结果如下图:请记住, 导入库文件的目录必须复制到工程目录中, 也就是说, 创建的 dll 和 lib 文件必须传输到工程目录中, 因为它们已经不在目录中, 而且, 尽管有新的路径 DllDemo. Doll, 我不知道为什么?

三。启用链接运行调用 DLL 。

以您在第二步的同样方式创建名为 DllTestOpt1 的控制应用程序, 并添加以下代码: [cpp] 查看普通副本 /DllTest1.cpp: 此文件指定控制平台程序的切入点 。 // #include "stdafx.h" #include <iostream> #include <windows.h> using namespace std; typedef int (*AddFunc)(int a, int b); int _tmain(int argc, _TCHAR* argv[]) { HMODULE hDll = LoadLibrary(_T("DllDemo.dll")); if (hDll != NULL) { AddFunc add = (AddFunc)GetProcAddress(hDll, "Add"); if (add != NULL) { cout<<add(2, 3)<<endl; } FreeLibrary(hDll); } while(1); } 运行结果如下图:

使用.. def 文件( 模块定义的文件) Export 方法 (而不是 _ declspec( dllexport) ):

第一个DLL项目题为DllDemo,内容如下: 然后创建页眉文件( MyCode) (MyCode) 。 (h) 和. Cpp 文件 (MyCode) 。 (cpp) 并插入以下代码: MyCode. hhead 文件: [cpp] 显示普通副本 #ifndef _MYCODE_H_ #define _MYCODE_H_ extern "C" int Add (int a , int b); #endif [cpp] 显示 MyCode. cpp 的普通副本 #include "MyCode.h" int Add ( int a , int b ) { return ( a + b ); } 然后包含一个模块定义文件( \ x\D\ 添加以下代号:[cpp]见纯文本 “DllDemo” // 字符串名称和工程名称在此情况下相同 。 EXPORTS Add @1;Export the Add function 编译工程,即刻生成DllDemo.dll文件。 DLL 是使用 dev 文件创建的, 客户端执行以下代码 : [cpp]  view plain  copy /DllTest2.cpp: 此文件指定控制平台程序的切入点 。 // #include "stdafx.h" #include <windows.h> #include <iostream> using namespace std; typedef int (*AddFunc)(int a, int b); int _tmain(int argc, _TCHAR* argv[]) { HMODULE hDll = LoadLibrary("DllDemo.dll"); if (hDll != NULL) { AddFunc add = (AddFunc)GetProcAddress(hDll, MAKEINTRESOURCE(1)); if (add != NULL) { cout<<add(2, 3)<<endl; } FreeLibrary(hDll); } while(1); } 下载工程代码 : 1. 此函数创建动态链接库。 通过 Declspec( dllexport) 导出函数 2 。 Generate 动态链接库 (在.. \

遇到的问题:

一个是导入图书馆时的目录问题。 在相应的文本中,问题1在相应的文本中,问题1, 并随后作出解释。 2。 字符集(是 Unicode 字符集或多字节集)、两个选项(一个是修改多字节设置的字符集,另一个是插入 _T ()),在文本中,问题23. 不清楚如何使用模块定义文件生成 DLL, 以及回复。

XTw.com.Cn系统网专业应用软件下载教程,免费windows10系统,win11,办公软件,OA办公系统,OA软件,办公自动化软件,开源系统,移动办公软件等信息,解决一体化的办公方案。

免责声明:本文中引用的各种信息及资料(包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主体(包括但不限于公司、媒体、协会等机构)的官方网站或公开发表的信息。内容仅供参考使用,不准确地方联系删除处理!

联系邮箱:773537036@qq.com