19.2 显式加载/隐式加载--《Windows核心编程》
部分笔记来自于:https://blog.csdn.net/blade1080/article/details/81364161
注:关于DLL存放位置,一般是放到可执行文件的目录下。
下面时加载程序的搜索顺序:
1) 包含可执行映像文件的目录。 2) 进程的当前目录。 3) Windows系统目录。 4) Windows目录。 5) PATH环境变量中列出的各个目录。
显式加载
调用 LoadLibrary/LoadLibrary 函数加载DLL。
隐式加载
是在系统启动时一次性把所有的DLL的导出函数加载到可执行文件中,需要用到.h和.lib文件。
创建DLL动态库
1、新建Dll项目
文件->新建->项目->Visual C++ win32控制台程序(填写项目名MyDll)->下一步->(应用程序类型)勾选:DLL,(附加选项)勾选:空项目->完成
2、添加新建项MyDll.h
#pragma once
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif
class MyDll
{
public:
MYDLL_API int Add(int a, int b); // 导出函数
MYDLL_API void myPrint(const char* s);
};
extern "C" MYDLL_API void printStr(const char* s);
extern "C" MYDLL_API extern int num; // 导出变量
dllimport 与 dllexport用于声明导入导出属性,其中_declspec(dllexport)用在dll程序中,用于说明这是导出的函数。而_declspec(dllimport)用在调用dll的程序中,用于说明这是从dll中导入的函数。
3、添加新建项MyDll.cpp
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include "MyDll.h"
#include <iostream>
int num = 10; // 定义变量
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int MyDll::Add(int a, int b)
{
return a + b;
}
void MyDll::myPrint(const char* s)
{
std::cout << s << std::endl;
}
void printStr(const char* s)
{
std::cout << s << std::endl;
}
4、编译生成
生成结果如下所示

隐式加载方式将使用到MyDll.h、MyDll.lib、MyDll.dll。
MyDll.lib需放置于项目的库搜索路径下,MyDll.dll需放置于项目生成的可执行文件同一目录下。

隐式加载方式使用DLL动态库
隐式加载是在系统启动时一次性把所有的DLL的导出函数加载到可执行文件中,需要用到.h和.lib文件。隐式加载的步骤为:
1、新建测试项目
文件->新建->项目->Visual C++ win32控制台程序(填写项目名testDll)->下一步-> (附加选项)勾选:空项目->完成
2、添加新建项main.cpp文件
注意包含DLL相关的那个头文件
#include <iostream>
#include "MyDll.h" // dll对应的那个头文件
// 在项目属性中添加dll对应.lib路径,附加依赖项里添加dll对应的.lib文件名
// 或者 #pragma comment (lib,"D:/Project Files/MyDll/Debug/MyDll.lib")
int main(void)
{
MyDll test;
std::cout << test.Add(2, 5) << std::endl;
test.myPrint("Func myPrint()");
printStr("Func printStr()");
printf("num = %d", num);
return 0;
}
3、项目属性中添加头文件路径

或者:将头文件拷贝至项目文件同一目录下,即项目默认的头文件搜索路径中。
4、项目属性中添加dll对应.lib路径

5、项目属性中附加依赖项里添加dll对应的.lib文件名

步骤4、5可使用以下代码替代。其中的路径可以使用相对路径(这里为绝对路径)。
#pragma comment (lib,"D:/Project Files/MyDll/Debug/MyDll.lib")
19.2 显式加载/隐式加载--《Windows核心编程》的更多相关文章
- selenium-webdriver中的显式等待与隐式等待
在selenium-webdriver中等待的方式简单可以概括为三种: 1 导入time包,调用time.sleep()的方法传入时间,这种方式也叫强制等待,固定死等一个时间 2 隐式等待,直接调用i ...
- 转】C#接口-显式接口和隐式接口的实现
[转]C#接口-显式接口和隐式接口的实现 C#中对于接口的实现方式有隐式接口和显式接口两种: 类和接口都能调用到,事实上这就是“隐式接口实现”. 那么“显示接口实现”是神马模样呢? interface ...
- C# Interface显式实现和隐式实现
c#中对接口的实现方式有两种:隐式实现和显式实现,之前一直没仔细看过,今天查了些资料,在这里整理一下. 隐式实现的例子 interface IChinese { string Speak(); } p ...
- 多态设计 zen of python poem 显式而非隐式 延迟赋值
总结 1.python支持延迟赋值,但是给调用者带来了困惑: 2.显式而非隐式,应当显式地指定要初始化的变量 class Card: def __init__(self, rank, suit): s ...
- C# 数据类型转换 显式转型、隐式转型、强制转型
C# 的类型转换有 显式转型 和 隐式转型 两种方式. 显式转型:有可能引发异常.精确度丢失及其他问题的转换方式.需要使用手段进行转换操作. 隐式转型:不会改变原有数据精确度.引发异常,不会发生任何问 ...
- (java)selenium webdriver学习---三种等待时间方法:显式等待,隐式等待,强制等待
selenium webdriver学习---三种等待时间方法:显式等待,隐式等待,强制等待 本例包括窗口最大化,刷新,切换到指定窗口,后退,前进,获取当前窗口url等操作: import java. ...
- Java并发之显式锁和隐式锁的区别
Java并发之显式锁和隐式锁的区别 在面试的过程中有可能会问到:在Java并发编程中,锁有两种实现:使用隐式锁和使用显示锁分别是什么?两者的区别是什么?所谓的显式锁和隐式锁的区别也就是说说Synchr ...
- Scala隐式转换和隐式参数
隐式转换 Scala提供的隐式转换和隐式参数功能,是非常有特色的功能.是Java等编程语言所没有的功能.它可以允许你手动指定,将某种类型的对象转换成其他类型的对象或者是给一个类增加方法.通过这些功能, ...
- Scala基础:闭包、柯里化、隐式转换和隐式参数
闭包,和js中的闭包一样,返回值依赖于声明在函数外部的一个或多个变量,那么这个函数就是闭包函数. val i: Int = 20 //函数func的方法体中使用了在func外部定义的变量 那func就 ...
- Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...
随机推荐
- freeswitch的gateway实现出中继的主备方案
概述 freeswitch是一款简单好用的VOIP开源软交换平台. 某些呼叫场景中,我们有2条出中继线路可选,2条出中继需要按照主备模式来配置,优先使用主中继呼叫,当主中继出现问题时,呼叫自动转移到备 ...
- JavaWeb+JDBC+Servlet+SqlServer实现登录功能
首先创建javaweb项目,可以参照以下: https://blog.csdn.net/u012532559/article/details/51013400 附上项目结构: 1.重写登录页面inde ...
- C语言基础之理论概述
C语言介绍 C语言是一种高级程序设计语言,由贝尔实验室的Dennis Ritchie在1972年开发.C语言是结构化编程语言,支持变量.数据类型.运算符.表达式.流程控制语句和函数等基本程序设计元素. ...
- Canal使用和安装总结
转载请注明出处: 1.定义 Canal 组件是一个基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费,支持将增量数据投递到下游消费者(如 Kafka.RocketMQ 等)或者存储(如 El ...
- pmp考试巩固知识点
1.冲刺评审会是需要相关的干系人参加的,在冲刺评审会上干系人可以审查并澄清角色.责任和管理模式2.采购中的争议,往往找合同和SOW,SOW是对需要采购的详细范围的描述,与供应商在可交付成果方面有争议时 ...
- 搞了个Blazor工具站,域名一次性买了10年!
大家好,我是沙漠尽头的狼. 在 Dotnet9 上线在线小工具和小游戏后,服务器的压力感觉挺大的,打开25个页面,内存占用170MB左右,CPU保持在60~70%,看来Server真不适合搞这类交互较 ...
- 使用Java分析器优化代码性能,解决OOM问题
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址 背景 最近我一直在做性能优化,对一个单机应用做性能优化.主要是 ...
- [转帖]全表扫描却产生大量db file sequential read一例
老熊 Oracle性能优化 2012-05-23 开发人员在进行新系统上线前的数据校验测试时,发现一条手工执行的SQL执行了超过1小时还没有返回结果.SQL很简单: SELECT * FROM MOB ...
- [转帖]Java连接 MySQL详细教程,分享复习经验和后台开发面经
(由于安装了汉化包,英文版的用户可以对应图标来操作) 选中菜单栏文件,之后选择项目结构 选择Libraries 点击+ ![在这里插入图片描述](https://img-blog.csdnimg.cn ...
- [转帖]UseG1GC垃圾回收技术解析
https://www.cnblogs.com/yuanzipeng/p/13374690.html 介绍 G1 GC,全称Garbage-First Garbage Collector,通过-XX: ...