文章为转载,原文出处https://blog.csdn.net/qq_29542611/article/details/86618902

前言
先简单介绍下DLL。DLL:Dynamic Link Library 动态链接库 是一个被其他应用程序调用的程序模块,其中封装了可以被调用的资源或函数。DLL 文件属于可执行文件,它符合Windows系统的PE文件格式,不过它是依附于EXE文件创建的的进程来执行的,不能单独运行。为了演示调用DLL程序的2种方法,我们先建一个简单的DLL程序。

建一个简单的DLL程序
IDE 使用vs2015,新建工程DLLTest1,选择空项目,创建完毕 右击项目 -> 属性 -> 常规 -> 配置类型 选择 动态库.dll。还是上一张图吧。

添加头文件Calc.h 在头文件中添加导出函数add函数

#pragma once

extern "C" __declspec(dllexport) int add(int a, int b);

cpp文件中进行实现  

#include "Calc.h"

int add(int a, int b)
{
return a + b;
}

生成解决方案,在Debug下生成 DLLTest1.dll和DLLTest1.lib  

对DLL程序调用方式一

同样是新建空项目,添加main.cpp文件,将 DLLTest1.dll和DLLTest1.lib 拷贝到工程代码目录,然后项目添加添加现有项。项目目录如下
在这里插入图片描述

使用代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h> #pragma comment(lib,"DLLTest1.lib") extern "C" int add(int a, int b); // 静态调用DLL库
void StaticUse()
{
int sum = add(10, 20);
printf("静态调用,sum = %d\n", sum);
}

方式一 是静态调用,在连接阶段 将DLL库信息编写到EXE文件中,当调用DLL库中的函数是会加重DLL库。#pragma comment(lib,“DLLTest1”)告诉连机器需要在FirstDll.lib文件中找到DLL中导出函数的信息。  

对DLL程序调用方式二

方法一属于静态调用,其方式是通过链接器将DLL函数的导出函数写进可执行文件。现在使用第二种方式,相对前一种 是动态调用。动态调用不是链接时完成的,而是在运行时完成的。动态调用不会在可执行文件中写入DLL相关的信息。代码如下:

// 动态调用DLL库
void DynamicUse()
{
// 运行时加载DLL库
HMODULE module = LoadLibrary("DLLTest1.dll");
if (module == NULL)
{
printf("加载DLLTest1.dll动态库失败\n");
return;
}
typedef int(*AddFunc)(int, int); // 定义函数指针类型
AddFunc add;
// 导出函数地址
add = (AddFunc)GetProcAddress(module, "add"); int sum = add(100, 200);
printf("动态调用,sum = %d\n",sum);
}

用到了以下2个函数:  

// 根据DLL文件名 加载DLL
// suc,返回一个模块句柄
HMODULE WINAPI LoadLibrary(
_In_ LPCTSTR lpFileName
);
// suc,返回lpProcName指向的函数名的函数地址。
FARPROC GetProcAddress(
HMODULE hModule,
LPCSTR lpProcName
);

测试

测试代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h> #pragma comment(lib,"DLLTest1.lib") extern "C" int add(int a, int b); // 静态调用DLL库
void StaticUse()
{
int sum = add(10, 20);
printf("静态调用,sum = %d\n", sum);
} // 动态调用DLL库
void DynamicUse()
{
HMODULE module = LoadLibrary("DLLTest1.dll");
if (module == NULL)
{
printf("加载DLLTest1.dll动态库失败\n");
return;
}
typedef int(*AddFunc)(int, int); // 定义函数指针类型
AddFunc add;
add = (AddFunc)GetProcAddress(module, "add"); int sum = add(100, 200);
printf("动态调用,sum = %d\n", sum);
} int main(char argc, char* argv[])
{
StaticUse();
DynamicUse();
system("pause");
return 0;
}

验证结果,和我们想象的一样。  

  

C/C++:Windows编程—调用DLL程序的2种方法(转载)的更多相关文章

  1. [Windows][VC]开机自动启动程序的几种方法

    原文:[Windows][VC]开机自动启动程序的几种方法 很多监控软件要求软件能够在系统重新启动后不用用户去点击图标启动项目,而是直接能够启动运行,方法是写注册表Software\\Microsof ...

  2. java中调用dll文件的两种方法

    一中是用JNA方法,另外是用JNative方法,两种都是转载来的, JNA地址:http://blog.csdn.net/shendl/article/details/3589676   JNativ ...

  3. VC++开机自动启动程序的几种方法 (转载)

    转载:http://blog.csdn.net/zhazhiqiang/article/details/51909703 很多监控软件要求软件能够在系统重新启动后不用用户去点击图标启动项目,而是直接能 ...

  4. windows下获取IP地址的两种方法

    windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...

  5. 请阐述调用Activity有哪几种方法,并写出相关的Java代码

    请阐述调用Activity有哪几种方法,并写出相关的Java代码. 答案:可以采用两种方式调用Activity:显示调用和隐式调用.显示调用直接指定了Activity,代码如下: Intent int ...

  6. android中退出当前应用程序的四种方法

    android中退出当前应用程序的四种方法 [IT168 技术]Android程序有很多Activity,比如说主窗口A,调用了子窗口B,如果在B中直接finish(), 接下里显示的是A.在B中如何 ...

  7. android 安全退出应用程序的几种方法

    android 安全退出应用程序的几种方法 正常关闭应用程序: 当应用不再使用时,通常需要关闭应用,可以使用以下三种方法关闭android应用: 第一种方法:首先获取当前进程的id,然后杀死该进程.a ...

  8. Tomcat部署发布JSP应用程序的三种方法 (转)

    Tomcat部署发布JSP应用程序的三种方法     1.直接放到Webapps目录下      Tomcat的Webapps目录是Tomcat默认的应用目录,当服务器启动时,会加载所有这个目录下的应 ...

  9. ASP.NET,C#后台调用前台javascript的五种方法

    C#后台调用前台javascript的五种方法 由于项目需要,用到其他项目组用VC开发的组件,在web后台代码无法访问这个组件,所以只好通过后台调用前台的javascript,从而操作这个组件.在网上 ...

随机推荐

  1. C/C++ GBK和UTF8之间的转换

    { 关于GBK和UTF-8之间的转换,很多初学者会很迷茫. 一般来说GBK和UTF-8是文字的编码方式,其对应的内码是不一样的,所以GBK和UTF-8的转换需要对内码进行一一映射,然后进行转换. 对于 ...

  2. git ,报403错误,完美解决方案

    首先命令行操作结果如下: root@zhiren-PowerEdge-T110-II:/zrun# git clone https://git.coding.net/xxxxxxxx/xxxx.git ...

  3. vscode开发vue项目保存时自动执行lint进行修复

    vscode下载eslint插件 vscode进行设置 找到settings.json 在里面写入如下内容进行保存 {     "eslint.autoFixOnSave": tr ...

  4. C++语言编程基础

    C++程序设计语言可以看作C语言的改进和升级,不仅完全兼容了C语言的语法和函数库,还引入了面向对象.运算符重载.多态性.数据流和模板等最新的编程思想.极大地保证了源代码的生产率.质量和可重用性.GNU ...

  5. MVC 中对返回的 data 进行压缩

    在webAPI 中返回数据,在数据量比较大的情况的下,返回的data 也可能比较大,有时候可能大于1兆,因此对数据进行压缩能极大的提高数据下载到客户端的时间,提高页面的加载速度. 思路: 在web a ...

  6. jenkins的api操作

    jenkins-client 实现方式 jenkins-client 底层是使用 HttpClient HttpPost 发送post 请求实现的,是将 REST API 封装了一下 添加依赖 < ...

  7. 使用java.util.Properties工具制作自定义访问配置文件信息

    import ch.qos.logback.classic.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; im ...

  8. 测试常用——linux 基础命令

    测试常用 的 linux 基础命令 1,查看服务器日志vi 查看文件(查找关键字:exception/exception  :  从上往下找,按n查找下一个关键字,按shift+n查找上一个关键字?e ...

  9. (转)C#中String跟string的“区别”

    string是c#中的类,String是.net Framework的类(在C# IDE中不会显示蓝色) C# string映射为.net Framework的String 如果用string,编译器 ...

  10. 1、Locust压力测试环境搭建

    环境准备:阿里云服务器一台.python2.7.pip Locust 介绍 Locust 是一个开源负载测试工具.使用 Python 代码定义用户行为,也可以仿真百万个用户. Locust 简单易用, ...