部分笔记来自于: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核心编程》的更多相关文章

  1. selenium-webdriver中的显式等待与隐式等待

    在selenium-webdriver中等待的方式简单可以概括为三种: 1 导入time包,调用time.sleep()的方法传入时间,这种方式也叫强制等待,固定死等一个时间 2 隐式等待,直接调用i ...

  2. 转】C#接口-显式接口和隐式接口的实现

    [转]C#接口-显式接口和隐式接口的实现 C#中对于接口的实现方式有隐式接口和显式接口两种: 类和接口都能调用到,事实上这就是“隐式接口实现”. 那么“显示接口实现”是神马模样呢? interface ...

  3. C# Interface显式实现和隐式实现

    c#中对接口的实现方式有两种:隐式实现和显式实现,之前一直没仔细看过,今天查了些资料,在这里整理一下. 隐式实现的例子 interface IChinese { string Speak(); } p ...

  4. 多态设计 zen of python poem 显式而非隐式 延迟赋值

    总结 1.python支持延迟赋值,但是给调用者带来了困惑: 2.显式而非隐式,应当显式地指定要初始化的变量 class Card: def __init__(self, rank, suit): s ...

  5. C# 数据类型转换 显式转型、隐式转型、强制转型

    C# 的类型转换有 显式转型 和 隐式转型 两种方式. 显式转型:有可能引发异常.精确度丢失及其他问题的转换方式.需要使用手段进行转换操作. 隐式转型:不会改变原有数据精确度.引发异常,不会发生任何问 ...

  6. (java)selenium webdriver学习---三种等待时间方法:显式等待,隐式等待,强制等待

    selenium webdriver学习---三种等待时间方法:显式等待,隐式等待,强制等待 本例包括窗口最大化,刷新,切换到指定窗口,后退,前进,获取当前窗口url等操作: import java. ...

  7. Java并发之显式锁和隐式锁的区别

    Java并发之显式锁和隐式锁的区别 在面试的过程中有可能会问到:在Java并发编程中,锁有两种实现:使用隐式锁和使用显示锁分别是什么?两者的区别是什么?所谓的显式锁和隐式锁的区别也就是说说Synchr ...

  8. Scala隐式转换和隐式参数

    隐式转换 Scala提供的隐式转换和隐式参数功能,是非常有特色的功能.是Java等编程语言所没有的功能.它可以允许你手动指定,将某种类型的对象转换成其他类型的对象或者是给一个类增加方法.通过这些功能, ...

  9. Scala基础:闭包、柯里化、隐式转换和隐式参数

    闭包,和js中的闭包一样,返回值依赖于声明在函数外部的一个或多个变量,那么这个函数就是闭包函数. val i: Int = 20 //函数func的方法体中使用了在func外部定义的变量 那func就 ...

  10. Scala 深入浅出实战经典 第61讲:Scala中隐式参数与隐式转换的联合使用实战详解及其在Spark中的应用源码解析

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载: 百度云盘:http://pan.baidu.com/s/1c0noOt ...

随机推荐

  1. 【驱动】以太网扫盲(二)phy寄存器简介

    PHY 寄存器的地址空间为 5 位,从 0 到 31 最多可以定义 32 个寄存器(随着芯片功能不断增加,很多 PHY 芯片采用分页技术来扩展地址空间以定义更多的寄存器),IEEE802.3 定义了地 ...

  2. CMake学习,我们怎么从零开始狂写大型项目

    CMake 说明 cmake的定义是什么 ?-----高级编译配置工具 当多个人用不同的语言或者编译器开发一个项目,最终要输出一个可执行文件或者共享库(dll,so等等)这时候神器就出现了-----C ...

  3. 解决xshell-ssh远程登录,只能通过public key登录导致无法登录的情况

    xshell无法通过密码登录的问题如下: 1.登录主机:vi /etc/ssh/sshd_config 2.搜索关键字:PasswordAuthentication 3.将PasswordAuthen ...

  4. idea相关配置及插件安装

    对idea相关的配置及好用的插件进行总结下. 一.idea 破解码及配置:https://www.jb51.net/softs/672190.html 二.idea插件: 1.findBugs-ide ...

  5. 08-避免Latch的产生

    1.Latch简介 Latch就是锁存器,是一种在异步电路系统中,对输入信号电平敏感的单元,用来存储信息 锁存器在数据未锁存时,输出端的信号随输入信号变化,就像信号通过一个缓冲器,一旦锁存信号有效,数 ...

  6. java - 字符串转数字

    Integer.valueOf("str").intValue(): Integer.valueOf("123").intValue():

  7. Laravel - 虚拟主机引入静态资源

    一. 注意: 引用的静态文件要放在根目录,不要放在assets目录下 二. 引入方法 1.  模板中引入 css      <link rel="stylesheet" hr ...

  8. Python Code_01

    author : 写bug的盼盼 development time : 2021/8/27 19:41 输出数字 print(520) 输出字符串 print('HelloWorld') print( ...

  9. [转帖]CoreDNS loop 插件异常问题

    https://zhuanlan.zhihu.com/p/476611162   背景 最近有遇到一个客户集群,发现集群中的 CoreDNS 老是异常 (loop 插件检测到有回路后进行 panic) ...

  10. 【DS】【AtCoder】Pakencamp 2022 Day2 H

    2023.6.30 Problem Link 有 \(n\) 个帮派在打架,每个帮派有一个大小 \(a_i\),每相邻两个帮派有一个仇恨度 \(b_i\).现在有 \(Q\) 次单点修改 \(a_i\ ...