背景描述:
现需要在项目 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的函数。
原文出处:
http://liyanliang.net/index.php/2021/03/15/callafunctioninanotherproject/