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

转载自  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;
}


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


完整项目

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

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值