最近在项目中,经常用到使用对方提供框架,由自己提供动态库实现的形式,找个空闲的时间讲大概的流程阐述出来,一是为近期的工作总结,二是想获得大家的一些批评和指正。
1、外单位提供了一个程序的基础框架,其中实现应该相当复杂,我这里只能做一个大概的猜测。
主程序如下,调用了其自身的主动态库:
1 intmain()2 {3 HINSTANCE hDll = LoadLibraryA("TestObserver.dll");4 system("pause");5 return 0;6 }
采用单件和观察者模式实现主动态库管理类:
1 #pragma once
2 #include "TestObserver_export.h"
3 #include "global_api.h"
4
5 classCDllMgr6 {7 public:8 ~CDllMgr(void);9
10 static CDllMgr* GetInstance(); //获取单件实例
11
12 void Attach(CObserverInterface* handel); //注册观察者
13
14 void Detach(); //释放
15
16 voidUseCallBack();17
18 private:19 CDllMgr(void); //声明构造函数为private
20 CObserverInterface*m_handel;21 };
1 #include "StdAfx.h"
2 #include "DllMgr.h"
3
4 CDllMgr::CDllMgr(void)5 {6 }7
8
9 CDllMgr::~CDllMgr(void)10 {11 Detach();12 }13
14 CDllMgr*CDllMgr::GetInstance()15 {16 staticCDllMgr instance;17 return &instance;18 }19
20 void CDllMgr::Attach(CObserverInterface*handel)21 {22 m_handel =handel;23 }24
25 voidCDllMgr::Detach()26 {27 if (m_handel !=NULL)28 {29 deletem_handel;30 }31 }32
33 voidCDllMgr::UseCallBack()34 {35 m_handel->CallBackTest();36 }
提供给用户一些接口,以供主框架回调:
1 #ifndef global_api_h__2 #define global_api_h__
3
4 #include "TestObserver_export.h"
5
6 classTEST_OBSERVER_API CObserverInterface7 {8 public:9 virtual void CallBackTest() = 0; //用户继承接口并实现
10 };11
12 void TEST_OBSERVER_API AttachMgr(CObserverInterface* handel); //用户注册观察者
13
14 #endif //global_api_h__
其中"TestObserver_export.h"为定义导出类文件:
1 #ifndef TESTOBSERVER_EXPORTS2 #define TEST_OBSERVER_API __declspec(dllimport)
3 #else
4 #define TEST_OBSERVER_API __declspec(dllexport)
5 #endif
这里使用dllmain.h简单模拟主框架对用户实现的调用
1 //dllmain.cpp : 定义 DLL 应用程序的入口点。
2 #include "stdafx.h"
3 #include
4 #include "DllMgr.h"
5
6
7 BOOL APIENTRY DllMain( HMODULE hModule,8 DWORD ul_reason_for_call,9 LPVOID lpReserved10 )11 {12 HINSTANCE hDll = LoadLibraryA("UserDll.dll");13 switch(ul_reason_for_call)14 {15 caseDLL_PROCESS_ATTACH:16 CDllMgr::GetInstance()->UseCallBack();17 break;18 caseDLL_PROCESS_DETACH:19 CDllMgr::GetInstance()->Detach();20 break;21 }22 returnTRUE;23 }
2.第二部分为用户提供的动态库以供主框架调用。
用户实现了虚接口:
1 #pragma once
2 #include "../../TestObserver/TestObserver/global_api.h"
3
4 classCUserTest:5 publicCObserverInterface6 {7 public:8 CUserTest(void);9 ~CUserTest(void);10
11 virtual void CallBackTest(); //实现虚接口
12 };
1 #include "StdAfx.h"
2 #include "UserTest.h"
3 #include
4
5 CUserTest::CUserTest(void)6 {7 }8
9 CUserTest::~CUserTest(void)10 {11 }12
13 voidCUserTest::CallBackTest()14 {15 printf("User define behavior");16 }
用户需要利用主框架提供的全局接口对自身组件注册观察者:
1 //dllmain.cpp : 定义 DLL 应用程序的入口点。
2 #include "stdafx.h"
3 #include "UserTest.h"
4
5 BOOL APIENTRY DllMain( HMODULE hModule,6 DWORD ul_reason_for_call,7 LPVOID lpReserved8 )9 {10 if (DLL_PROCESS_ATTACH ==ul_reason_for_call)11 {12 CUserTest test;13 AttachMgr(&test);14 }15 returnTRUE;16 }
这样当主框架起来后,用户提供的动态库也被调起来了。
3.回顾一下自己在实现过程中遇到的一些问题:
1、问题描述:LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
解决方案:项目—属性—配置属性—清单工具—输入输出—嵌入清单,改为“否”。
2、问题描述:error LNK2019: 无法解析的外部符号 [email protected],该符号在函数 ___tmainCRTStartup 中被引用
解决方案:见 https://blog.csdn.net/playstudy/article/details/6661868
原文:https://www.cnblogs.com/LiQuid/p/10629793.html