[例7.16]实现一个扩展MFC DLL来增强CStatic:DECLARE_DYNAMIC声明和IMPLEMENT_DYNAMIC的介绍

书籍:《Visual C++ 2017从入门到精通》的2.3.8 Win32控件编程

环境:visual studio 2022

在 MFC DLL 中导出类时,​​是否必须使用 DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC 宏​​取决于具体需求,但以下情况 ​​必须使用​​:


​必须使用的情况​

1. ​​需要运行时类型识别(RTTI)​
  • ​功能​​:支持 IsKindOfRUNTIME_CLASS 等动态类型检查。
  • ​场景​​:
    • 通过基类指针动态创建派生类对象(如工厂模式)。
    • 使用 MFC 的序列化框架(CArchive)。
    • 消息映射(BEGIN_MESSAGE_MAP)依赖 RTTI 确定消息处理函数归属。
2. ​类继承自 CObject 或 MFC 基类​
  • ​规则​​:MFC 要求从 CObject 派生的类必须声明 DECLARE_DYNAMIC,否则无法使用 MFC 的动态特性。
  • ​示例​​:
    class AFX_EXT_CLASS CMyClass : public CObject {  // 必须声明 DECLARE_DYNAMIC
        DECLARE_DYNAMIC(CMyClass)
        // ...
    };
3. ​​跨模块动态创建对象​
  • ​场景​​:在客户端通过 RUNTIME_CLASS 或 CObject::IsKindOf 验证对象类型时,必须定义 CRuntimeClass 信息。

​可以省略的情况​

1. ​​纯 C 风格函数导出​
  • ​场景​​:仅导出普通函数或非 MFC 类,无需 RTTI。
  • ​示例​​:
    extern "C" __declspec(dllexport) int Add(int a, int b) {
        return a + b;
    }
2. ​​不涉及 MFC 框架的类​
  • ​场景​​:类不继承自 MFC 基类(如 CObject),且不依赖 MFC 的动态特性。

​不使用的风险​

​场景​​问题表现​
未声明 DECLARE_DYNAMIC1. IsKindOf 返回 FALSE
2. 消息映射失效
3. 序列化时抛出异常
未实现 IMPLEMENT_DYNAMIC1. CRuntimeClass 结构体未定义
2. 运行时访问 GetRuntimeClass() 崩溃

​正确使用示例​

​头文件(导出类声明)​
// MyExportClass.h
#pragma once
#include <afxwin.h>

#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

class MYDLL_API CMyExportClass : public CObject {
    DECLARE_DYNAMIC(CMyExportClass)  // 必须声明
public:
    CMyExportClass();
    virtual ~CMyExportClass();
};
​实现文件(导出类定义)​
// MyExportClass.cpp
#include "MyExportClass.h"

IMPLEMENT_DYNAMIC(CMyExportClass, CObject)  // 必须实现

CMyExportClass::CMyExportClass() {}
CMyExportClass::~CMyExportClass() {}

​替代方案​

若需导出类但不使用 RTTI,可手动定义 CRuntimeClass(不推荐):

// 手动定义(仅限高级场景)
extern "C" {
    CRuntimeClass g_RuntimeClass_CMyClass = {
        "CMyClass",        // 类名
        sizeof(CMyClass),  // 类大小
        0xFFFF,            // Schema 版本
        NULL,              // 动态创建函数
        RUNTIME_CLASS(CObject)  // 基类信息
    };
}

​总结​

​是否必须使用宏​​条件​
✅ 必须使用类继承自 CObject、需 RTTI、使用消息映射或序列化。
❌ 可省略纯 C 函数导出、非 MFC 类且无需动态特性。

​建议​​:在 MFC DLL 开发中,​始终使用 DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC​,以确保与框架的兼容性和功能完整性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值