本文回顾学习一下Windows动态链接库:dll与exe相互调用问题。一般滴,exe用来调用dll中的类或函数,但是dll中也可以调用exe中的类或函数,本文做一些尝试总结。

dll程序:

Calculator.h 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 
// Calculator.h: interface for the Calculator class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ALCULATOR_H__D072BBB5_615B_45A9_9864_80C2291FA695__INCLUDED_)
#define AFX_ALCULATOR_H__D072BBB5_615B_45A9_9864_80C2291FA695__INCLUDED_

#pragma once
#endif // _MSC_VER > 1000

class IHelper;
class Helper;
class _declspec(dllexport) Calculator
{
public:
    Calculator();
    ~Calculator();

void registerHelper(IHelper *iHelper);
    void registerHelper(Helper  *helper);
    
    int add(int num1, int num2);
    int sub(int num1, int num2);
    
private:
    IHelper     *m_iHelper;
    Helper      *m_helper;
    
};

extern "C" _declspec(dllexport) Calculator *getCalculator();

#endif // !defined(AFX_ALCULATOR_H__D072BBB5_615B_45A9_9864_80C2291FA695__INCLUDED_)

 Calculator.cpp 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 
// Calculator.cpp: implementation of the Calculator class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Calculator.h"
#include "../vs_dll_caller/Helper.h"

#include "../vs_dll_caller/Helper.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Calculator::Calculator()
{
    
}

Calculator::~Calculator()
{
    
}

void Calculator::registerHelper(IHelper *iHelper)
{
    m_iHelper = iHelper;
}

void Calculator::registerHelper(Helper *helper)
{
    m_helper = helper;
}

int Calculator::add(int num1, int num2)
{
    m_iHelper->print("do add!");
    return num1 + num2;
}

int Calculator::sub(int num1, int num2)
{
    m_iHelper->print("do sub!");
    ;
}

Calculator *getCalculator()
{
    return new Calculator();
}

exe程序:

 IHelper.h
1
2
3
4
5
6
7
8
9
10
11
 
#pragma once
/************************************************************************/
// 抽象类                                                               */
// 该类在exe中,方便dll中调用
/************************************************************************/

class IHelper
{
public:
    ;
};

 Helper.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
// Helper.h: interface for the Helper class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_HELPER_H__9234DC8C_56CC_4765_BDA6_276F30C52221__INCLUDED_)
#define AFX_HELPER_H__9234DC8C_56CC_4765_BDA6_276F30C52221__INCLUDED_

#pragma once
#endif // _MSC_VER > 1000

#include "iHelper.h"

class Helper
    : public IHelper  
{
public:
    Helper();
    virtual ~Helper();

virtual void print(const char *str);

};

#endif // !defined(AFX_HELPER_H__9234DC8C_56CC_4765_BDA6_276F30C52221__INCLUDED_)

 Helper.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
// Helper.cpp: implementation of the Helper class.
//
//////////////////////////////////////////////////////////////////////

#include "Helper.h"
#include <iostream>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Helper::Helper()
{

}

Helper::~Helper()
{

}

void Helper::print(const char *str)
{
    std::cout << str << " ";
}

 main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 
#include <Windows.h>
#include <tchar.h>
#include <iostream>
#include "Helper.h"
#include "../vs_dll/Calculator.h"

typedef Calculator*(*Cal)();

int main()
{
    std::cout << "Hello World!\n";

// 隐式调用
    std::cout << "\n隐式调用" << std::endl;
    Calculator cal;
    // 回调指针给dll
    IHelper *helper = new Helper();
    cal.registerHelper(helper);
    );
    std::cout << "cal.add = " << num_add << std::endl;
    );
    std::cout << "cal.sub = " << num_sub << std::endl;

// 显式调用
    std::cout << "\n显式调用" << std::endl;
    HMODULE hDll = ::LoadLibrary("../Debug/vs_dll.dll");
    if (hDll != NULL)
    {
        Cal cal = (Cal)GetProcAddress(hDll, "getCalculator");
        Calculator *pCal = cal();
        // 回调指针给dll
        IHelper *helper = new Helper();
        pCal->registerHelper(helper);
        );
        std::cout << "pCal->add = " << num_add << std::endl;
        );
        std::cout << "pCal->sub = " << num_sub << std::endl;

}

std::cin.get();
    ;
}

总结:一般滴,dll是用来被exe调用的,如果dll要调用exe中的类,可以给dll注册一个该类的指针即可,而且该指针为抽象类指针。

Windows动态链接库:dll与exe相互调用问题的更多相关文章

  1. Golang编写Windows动态链接库(DLL)及C调用范例

    一.准备. 1.GoLang在1.10版本之后开始支持编译windows动态链接库,可以打开命令行工具使用go version 查看自己的go版本. 2.你的电脑上需要gcc,如果没有的话[点击这里] ...

  2. Windows 动态链接库DLL使用

    转载:https://blog.csdn.net/heyabo/article/details/8721611 转载:https://www.cnblogs.com/jin521/p/5598529. ...

  3. windows c dll的创建与调用

    DLL代码: // TestDynamic.cpp: implementation of the TestDynamic class. // ///////////////////////////// ...

  4. Windows动态链接库DLL

    1.什么是DLLDLL,即动态链接库,是包含若干个函数的库文件,可供其他程序运行时调用. 2.DLL的优缺点优点:代码重用,可供多个程序同时调用 缺点:易发生版本冲突当新版本的动态链接库不兼容旧版本时 ...

  5. C/C++/动态链接库DLL中函数的调用约定与名称修饰

    参见:http://blog.twofei.com/cc/impl/calling-convension.html 调用约定(Calling Convention)是指在程序设计语言中为了实现函数调用 ...

  6. DLL与EXE之间的通讯调用 以及 回调函数的线程执行空间

    dll 与 exe 之间的通讯方式有很多种, 本文采用回调函数的方法实现, 本文也将研究多线程,多模块的情况下,回调函数所在的线程, 啥也不说了,先附上代码: 下面的是dll模块的的, dll的工程文 ...

  7. VC++动态链接库(DLL)编程深入浅出(zz)

    VC++动态链接库(DLL)编程深入浅出(zz) 1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用 ...

  8. VC++动态链接库(DLL)编程深入浅出

    1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量.函数或类.在仓库的发展史上经历了“无库-静 ...

  9. VC++动态链接库(DLL)编程深入浅出(一)

    1.概论 先来阐述一下DLL(Dynamic Linkable Library)的概念,你可以简单的把DLL看成一种仓库,它提供给你一些可以直接拿来用的变量.函数或类.在仓库的发展史上经历了“无库-静 ...

随机推荐

  1. iOS 唤起APP之URL Scheme

    什么是URL Scheme 简单的说,由于苹果选择使用沙盒机制来保障用户的隐私和安全,APP只能访问自己沙盒数据,但同时也阻碍了应用间合理的信息共享.因此苹果提供了一个可以在APP之间跳转的方法:UR ...

  2. MySQL分组查询统计

    GROUP BY 1.有个店铺表,字段为区域id,设备数量,店铺名称,如下: 2.如何按区域 district 统计 每个区域的设备数量,SQL如下 SELECT district, SUM( dev ...

  3. Docker 类面试题(常见问题)

    Docker 常见问题汇总   镜像相关 1.如何批量清理临时镜像文件? 可以使用sudo docker rmi $(sudo docker images -q -f danging=true)命令 ...

  4. Mysql类

    架构层面可以采用读写分离,主从复制等等,在数据库前端加cache,如memcache,用于用户登录,商品查询     1.mysql优化的原则是什么? 答: 1.mysql的优化首先要从设计表的过程中 ...

  5. Jmeter+ant+Jenkins构建接口自动化测试时构建失败 提示:Fatal Error! 字符引用 "&#原因

    Jmeter+ant+Jenkins构建接口自动化测试时构建失败 提示:Fatal Error! 字符引用 "&#原因:接口响应数据中有&#

  6. Oracle 双机热备+双机冷备+负载均衡

    引用地址:https://wenku.baidu.com/view/7cca62f1ddccda38366baf7f.html SQL Server 2008 R2双机热备 引用地址:https:// ...

  7. Linux shell 判断字符串为空等常用命令

    1.判断字符串为空 if [ -z "$str" ]; then echo "empty string" fi 2.判断文件是否存在 if [ -f /home ...

  8. Python自动化运维之高级函数

    本帖最后由 陈泽 于 2018-6-20 17:31 编辑 一.协程 1.1协程的概念 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程.(其实并没 ...

  9. 2、zabbix3.4的安装

    系统版本:centos7 数据库版本:mysql二进制安装5.7 zabbix:阿里云安装3.4 一.Zabbix的安装 Zabbix3.4版本官方安装手册链接:https://www.zabbix. ...

  10. tensorboard运行使用(排坑)记录一

    首先运行如下代码(路径根据你自己的要求更改) writer = tf.summary.FileWriter("G:/tensorflow/graph", tf.get_defaul ...