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  

//////////////////////////////////////////////////////////////////////
// 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  
#include  
#include  
#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);
    
int  num_add = cal.add( 3 2 );
    std::cout << 
"cal.add = "  << num_add << std::endl;
    
int  num_sub = cal.sub( 3 2 );
    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);
        
int  num_add = pCal->add( 3 2 );
        std::cout << 
"pCal->add = "  << num_add << std::endl;
        
int  num_sub = pCal->sub( 3 2 );
        std::cout << 
"pCal->sub = "  << num_sub << std::endl;

    }

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

Windows动态链接库:dll与exe相互调用问题_第1张图片

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

你可能感兴趣的