Windows动态链接库:dll与exe相互调用问题

本文回顾学习一下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_

#if _MSC_VER > 1000
#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!");
    
return num1 >= num2 ? num1 - num2 : -1;
}

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:
    
virtual void print(const char *str) = 0;
};
 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_

#if _MSC_VER > 1000
#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! ";

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

    
// 显式调用
    std::cout << " 显式调用" << 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);
        
int num_add = pCal->add(32);
        std::cout << 
"pCal->add = " << num_add << std::endl;
        
int num_sub = pCal->sub(32);
        std::cout << 
"pCal->sub = " << num_sub << std::endl;

    }

    std::cin.get();
    
return 0;
}

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

原文地址:https://www.cnblogs.com/MakeView660/p/11654766.html