C/C++:Windows编程—调用DLL程序的2种方法

前言

先简单介绍下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;
}

验证结果,和我们想象的一样。
在这里插入图片描述

完整项目

如果 有需要,这个2个工程这里下载

  • 49
    点赞
  • 236
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 动态链接库(Dynamic Link Library,简称“DLL”)是一Windows操作系统下的共享库文件,它可以被多个应用程序共享调用,能够方便多个程序之间共享代码和数据。而动态调用DLL就是在程序运行时,动态地加载DLL文件并执行其中的函数,它不需要把DLL文件中的函数载入内存,减少了程序的占用空间。 动态调用DLL的过程一般包括以下几步: 1. 加载DLL程序使用LoadLibrary函数来加载指定的DLL文件,它返回一个可用于调用DLL函数的句柄。 2. 导入DLL函数:使用GetProcAddress函数,根据DLL函数名称获得函数地址,使其可被调用。 3. 调用DLL函数:将DLL函数地址转换为正确的函数类型,传入参数并调用DLL函数。 4. 卸载DLL使用FreeLibrary函数卸载已加载的DLL文件,释放内存空间。 动态调用DLL可以使代码更具灵活性和可维护性,适用于需要动态扩展或修改功能的程序。同时,它也提高了程序的效率和整体性能,减少了对系统资源的占用。不过,动态调用DLL需要谨慎使用,因为错误的调用会导致程序崩溃或出现安全漏洞。要注意正确传递函数参数和释放内存空间,避免内存泄漏问题。 ### 回答2: 动态链接库(Dynamic Link Library,DLL)是在Windows系统中常用的一辅助程序。动态调用DLL意味着在运行时加载DLL,并使用其中的函数。相比于静态调用(在编译时将DLL函数链接到代码中),动态调用具有更大的灵活性和可重用性。 动态链接库通常包括一组函数,这些函数可以通过导出表(Export Table)进行访问。为了使用DLL中的函数,首先需要使用LoadLibrary函数将DLL加载到进程的地址空间中。加载完成后,还需要使用GetProcAddress函数获取DLL中特定函数的地址。 一旦获得了DLL中函数的地址,就可以使用类似于函数指针的方式调用它们。通过使用GetProcAddress函数返回的地址指针,将函数的参数传递到DLL函数中进行处理。当调用完成后,使用FreeLibrary函数将DLL从进程的地址空间中卸载。 总的来说,使用动态调用DLL可以实现在程序运行时动态加载和链接DLL中的函数,从而提供更大的灵活性和可重用性。 ### 回答3: 动态调用DLL,是指在程序运行期间,通过代码调用动态链接库(DLL)中的函数或方法,实现特定功能的过程。相对于静态链接库,动态调用DLL具有更加灵活和高效的特点。 在Windows平台上,可以使用Win32 API中提供的LoadLibrary、GetProcAddress等函数实现动态调用DLL。LoadLibrary函数用于加载DLL文件,并返回一个句柄,可以通过这个句柄获取DLL中导出函数的地址。而GetProcAddress函数则可以根据函数名称获取函数地址,即导出函数表中的函数指针。 使用动态调用DLL,可以动态地载入需要的库,从而减少了程序的运行时内存开支,而且可以实现不同版本动态链接库的切换。此外,动态调用DLL还可以实现模块化编程,使程序的各个部分之间更加独立和可重用。 需要注意的是,在使用动态调用DLL时,一定要确保DLL文件的正确性和可靠性。因为DLL文件的损坏或恶意篡改可能会导致程序崩溃或者安全漏洞。因此,在使用动态链接库时,务必进行严格的文件验证和权限控制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值