调用另外一个项目中的函数-设计模式解耦
背景描述
现需要在项目 CDP_cmd 中调用项目 CDP_dgnCalc 类CAnalRstHelper_JTGTJ212011中的函数:
BOOL GetElemValuePositiveOrNegativeMy(IN OUT TElemPosition& tElemPos,OUT double& dCtrlValue, BOOL bPositive);
解决方法
1.查看项目属性,发现项目CDP_cmd和项目CDP_dgnCalc均引用项目CDP_db,故可在CDP_db中添加一个纯虚基类(接口)。
IAnalRstHelper_JTGTJ212011.h
#pragma once class CNSDocBase; struct TElemPosition; class CAnalRstHelper_JTGTJ212011; #include "HeaderPre.h" class __MY_EXT_CLASS__ IAnalRstHelper_JTGTJ212011 { public: IAnalRstHelper_JTGTJ212011(void); virtual ~IAnalRstHelper_JTGTJ212011(void); static CAnalRstHelper_JTGTJ212011* GetInstance(); static void SetInstance(CAnalRstHelper_JTGTJ212011* pSingleton); // 多态 static void DeleteInstance(); protected: static CAnalRstHelper_JTGTJ212011* m_pSingleton; // 单例 public: // 下面这3个函数是我们需要在另外一个模块中调用的函数,把它们设为需接口 virtual BOOL GetElemValuePositiveOrNegativeMy(IN OUT TElemPosition& tElemPos,OUT double& dCtrlValue, BOOL bPositive) = 0; virtual BOOL GetElemValueMymax(IN const TElemPosition& tElemPos,OUT double& dCtrlValue) = 0; virtual BOOL GetElemValueAbsFzmax(IN const TElemPosition& tElemPos,OUT double& dCtrlValue, OUT BOOL bMax) = 0; }; #include "HeaderPost.h"
IAnalRstHelper_JTGTJ212011.cpp
#include "stdafx.h" #include "IAnalRstHelper_JTGTJ212011.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif class CAnalRstHelper_JTGTJ212011; CAnalRstHelper_JTGTJ212011* IAnalRstHelper_JTGTJ212011::m_pSingleton = nullptr; IAnalRstHelper_JTGTJ212011::IAnalRstHelper_JTGTJ212011() { } IAnalRstHelper_JTGTJ212011::~IAnalRstHelper_JTGTJ212011(void) { } CAnalRstHelper_JTGTJ212011* IAnalRstHelper_JTGTJ212011::GetInstance() { return m_pSingleton; } void IAnalRstHelper_JTGTJ212011::SetInstance(CAnalRstHelper_JTGTJ212011* pSingleton) { m_pSingleton = pSingleton; } void IAnalRstHelper_JTGTJ212011::DeleteInstance() { if (m_pSingleton) { delete m_pSingleton; m_pSingleton = nullptr; } }
2.使子类CAnalRstHelper_JTGTJ212011继承于虚基类IAnalRstHelper_JTGTJ212011
CAnalRstHelper_JTGTJ212011.h
#pragma once #include "../CDP_db/IAnalRstHelper_JTGTJ212011.h" #include "HeaderPre.h" class __MY_EXT_CLASS__ CAnalRstHelper_JTGTJ212011 : public IAnalRstHelper_JTGTJ212011 { public: CAnalRstHelper_JTGTJ212011(); CAnalRstHelper_JTGTJ212011(); virtual ~CAnalRstHelper_JTGTJ212011(void); public: virtual BOOL GetElemValueMymax(IN const TElemPosition& tElemPos,OUT double& dCtrlValue); virtual BOOL GetElemValuePositiveOrNegativeMy(IN OUT TElemPosition& tElemPos,OUT double& dCtrlValue, BOOL bPositive); virtual BOOL GetElemValueAbsFzmax(IN const TElemPosition& tElemPos,OUT double& dCtrlValue, OUT BOOL bMax); }; #include "HeaderPost.h"
CAnalRstHelper_JTGTJ212011.cpp
// 全局函数,初始化实例 void initDgnHelper() { // 多态 IAnalRstHelper_JTGTJ212011::SetInstance(new CAnalRstHelper_JTGTJ212011()); } void uninitDgnHelper() { IAnalRstHelper_JTGTJ212011::DeleteInstance(); }
3.在模块CDP_dgnCalc的dllmain.cpp中初始化实例和析构实例内存
dllmain.cpp
#include "stdafx.h" #include "dllmain.h" #include <afxwin.h> #include <afxdllx.h> #ifdef _DEBUG #define new DEBUG_NEW #endif // 声明为外部函数 extern void initDgnHelper(); extern void uninitDgnHelper(); extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { initDgnHelper(); // 初始化实例 } else if (dwReason == DLL_PROCESS_DETACH) { uninitDgnHelper(); // 析构实例 } return 1; // 犬牢 }
4.使用:在模块CDP_cmd的CMCtseDlg.cpp中调用函数
BOOL CCMCtseDlg::GetMaxPositiveOrMinNegativeMy(const TArraySpanInfo& taSpanInfo, OUT TElemPosition& ElemPos, BOOL bPositive) const { ElemPos = curElemPos; double dNextElemMy = 0.0; // 获取实例 CAnalRstHelper_JTGTJ212011* pAnalRstHelper = IAnalRstHelper_JTGTJ212011::GetInstance(); // 调用实例CAnalRstHelper_JTGTJ212011中的函数 if (!pAnalRstHelper->GetElemValuePositiveOrNegativeMy(nextElemPos, dNextElemMy, bPositive)) { ASSERT(0); } return TRUE; }
总结:
本方法主要利用C++的多态特性,在虚接口类中IAnalRstHelper_JTGTJ212011new一个CAnalRstHelper_JTGTJ212011的实例,在使用时虽然用的是接口类指针,但实际上其调用的是子类CAnalRstHelper_JTGTJ212011的函数。