模块化组件化实现独立的功能模块是软件设计的良好习惯,一般用实现为DLL。普通的DLL对外提供接口是采用导出函数接口,如果接口数量不大,只是50个以内,这种方式很适合;如果对外接口有上百个,导出函数接口就完全破坏了软件模块化分层设计的理念,使用接口非常麻烦,此情形采用C++/CLI导出类方式实现比较适合,即核心实现先C++ DLL,然后C++/CLI直接调用C++ DLL导出类,对外第三方工程提供CLI类接口。浮云E绘图以一个最简单的绘图模块为示例,详细介绍此方法的实现过程。
一、C++ DLL实现
本文只是为了介绍调用C++ dll导出类实现C++/CLI dll的完整过程,示例程序尽量简单。先用C++实现一个绘图组件dll。
C++ dll绘图主键设计构思
1. 绘图画布CFyView:CFyView继承自CWnd,是绘图画布窗口,并响应鼠标事件。
2. 绘图数据容器CChart:管理所有业务数据,(如需支持控件内滚轴,容器是虚拟画布)。
3. 曲线CCurve:曲线数据和曲线绘制。
C++ dll程序开发过程
1. 新建工程
选择C++ Windows 的 MFC动态链接库 --> 项目取名FyMfcDll,解决方案取名FyDemo --> Dll类型选 使用共享MFC DLL的常规 DLL
2. 创建绘图窗口类CFyView
新建类CFyView,继承于CWnd --> 添加窗口属性变量int m_crBackColor,重载窗口消息OnPaint、OnLButtonDblClk。
class CFyView : public CWnd
{
public:
CFyView();
virtual ~CFyView();
bool Create(HWND hParentWnd);
DECLARE_MESSAGE_MAP()
afx_msg void OnPaint();
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
public:
int m_crBackColor;
HWND m_hParentWnd;
CChart m_chart;
};
先创建好绘图窗口,方便调试绘图功能。接着往下实现绘图相关功能,等绘图功能实现后,再在CFyView里声明绘图相关对象,在OnPaint完成绘图呈现。
3. 创建数据管理器类CChart
数据管理类主要定义了曲线Curve对象集合、曲线标题、标题显示位置属性,以及添加、删除曲线,设置标题位置、绘图Draw等函数。
//作者:浮云E绘图,专业付费定制各类CAD/Viso等绘图编辑器、曲线控件等软件
//QQ:316868127
class CChart
{
public:
CChart();
virtual ~CChart();
void AddCurve(CCurve* curve);
void RemoveCurve(CCurve* curve);
void ClearCurves();
void Draw(CDC* dc);
void SetTitlePos(int x, int y);
void GetTitlePos(int& x, int& y);
CString GetTitle();
public:
CString m_sTitle;
CPtrArray m_curves;
int m_iTitleX;
int m_iTitleY;
};
实际商业项目中,数据管理容器管理着大量的业务对象,就曲线控件而言,比如曲线网格、坐标轴、图例等等数据。
4. 创建曲线类CCurve
曲线类主要定义了数据点集合CPoint数组、曲线名称、曲线线条宽度、颜色、线型等属性,主要方法是添加、清空点,以及画点连线函数Draw。
class CCurve
{
public:
CCurve(CString name);
virtual ~CCurve();
virtual bool AddPoint(CPoint* point);
virtual void ClearPoints();
virtual void Draw(CDC* dc);
public:
CString m_sName;
int MAX_POINT_COUNT = 100;
CPoint* m_pts = new CPoint[100]; //实际项目,此处创建的数组个数由外部程序传入
int m_nPointCount;
int m_nLineStyle;
int m_nLineWidth;
int m_crLineColor;
};
以上完成了C++ dll示例定义,完整的解决方案(包含4个工程)源码,在文本底部提供下载链接。在些C++ dll时,为了方便快捷的测试,可以先写一个C#测试工程,直接通过导出函数方式,测试C++ dll的核心流程。具体实现方式可参考 C#和VC++调用dll步骤,接口指针、字符串等类型对应关系https://blog.csdn.net/fyhhack/article/details/124903485
C++ dll直接导出函数测试接口
//作者:浮云E绘图,专业付费定制开发各类绘图软件
//QQ:316868127
extern "C" __declspec(dllexport) CFyView * NewFyChart()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return new CFyView();
}
extern "C" __declspec(dllexport) void DeleteFyChart(CFyView* fyView)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
delete fyView;
}
extern "C" __declspec(dllexport) bool CreateFyView(CFyView *fyView, HWND hParentW