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!\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; } |
总结:一般滴,dll是用来被exe调用的,如果dll要调用exe中的类,可以给dll注册一个该类的指针即可,而且该指针为抽象类指针。
希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯分享时的吝啬。