当前位置: 首页 > article >正文

MFC,DLL界面库设计注意

这个错误是由于CShapeBase类的虚表(vtable)没有正确生成或导出。在生成DLL时,需要确保虚函数表正确地在DLL中定义并导出,否则编译器会无法找到所需的符号,从而引发LNK2001错误。

为了解决这个问题,可以尝试以下步骤:

1. 确保所有项目都能正确识别导入/导出符号

在头文件中,使用__declspec(dllexport)__declspec(dllimport)的宏控制条件性地导入或导出符号。确保DLL项目定义了导出宏(例如MFCLIBRARY1_EXPORTS),而使用DLL的项目则不定义。

2. 使用MFCLIBRARY1_API宏控制导入/导出

使用宏MFCLIBRARY1_API修饰类声明,使得导入和导出在编译器之间切换。

3. 确保所有源文件包含同样的头文件

在实现文件中,不需要再使用__declspec(dllexport)。只需在头文件中声明,并确保所有相关代码文件都包含同样的头文件。

修改后的代码如下:

MFCLibrary1.h

#pragma once

#ifndef __AFXWIN_H__
    #error "在包含此文件之前包含 'pch.h' 以生成 PCH"
#endif

#include "resource.h"        // 主符号

#ifdef MFCLIBRARY1_EXPORTS
#define MFCLIBRARY1_API __declspec(dllexport)
#else
#define MFCLIBRARY1_API __declspec(dllimport)
#endif

class CMFCLibrary1App : public CWinApp
{
public:
    CMFCLibrary1App();

    // 重写
public:
    virtual BOOL InitInstance();

    DECLARE_MESSAGE_MAP()
};

class MFCLIBRARY1_API CShapeBase {
public:
    CShapeBase();
    virtual void OnDraw(CDC* pDC, int nCount);
    virtual ~CShapeBase() {}  // 添加虚析构函数确保生成虚表
};

// MFCLibrary1.cpp: 定义 DLL 的初始化例程。
//

#include "pch.h"
#include "framework.h"
#include "MFCLibrary1.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//
//TODO:  如果此 DLL 相对于 MFC DLL 是动态链接的,
//        则从此 DLL 导出的任何调入
//        MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
//        该函数的最前面。
//
//        例如: 
//
//        extern "C" BOOL PASCAL EXPORT ExportedFunction()
//        {
//            AFX_MANAGE_STATE(AfxGetStaticModuleState());
//            // 此处为普通函数体
//        }
//
//        此宏先于任何 MFC 调用
//        出现在每个函数中十分重要。  这意味着
//        它必须作为以下项中的第一个语句:
//        出现,甚至先于所有对象变量声明,
//        这是因为它们的构造函数可能生成 MFC
//        DLL 调用。
//
//        有关其他详细信息,
//        请参阅 MFC 技术说明 33 和 58。
//

// CMFCLibrary1App

BEGIN_MESSAGE_MAP(CMFCLibrary1App, CWinApp)
END_MESSAGE_MAP()


// CMFCLibrary1App 构造

CMFCLibrary1App::CMFCLibrary1App()
{
    // TODO:  在此处添加构造代码,
    // 将所有重要的初始化放置在 InitInstance 中
}


// 唯一的 CMFCLibrary1App 对象

CMFCLibrary1App theApp;


// CMFCLibrary1App 初始化

BOOL CMFCLibrary1App::InitInstance()
{
    CWinApp::InitInstance();

    return TRUE;
}


CShapeBase::CShapeBase() {
    // Constructor implementation
}

void CShapeBase::OnDraw(CDC* pDC, int nCount)
{
    // Function implementation
}

CShapeBase::~CShapeBase() {}

下面重点!!!

  • 在生成DLL的项目设置中,确保定义了MFCLIBRARY1_EXPORTS宏(在“项目属性”->“C/C++”->“预处理器”->“预处理器定义”中添加MFCLIBRARY1_EXPORTS)。
  • 确保链接器正确识别生成的DLL文件和对应的导入库文件。

http://www.kler.cn/a/382320.html

相关文章:

  • 【华硕天选5开机黑屏只有鼠标,调用资源管理器也无法黑屏状态的一种解决方式】
  • ctfshow web文件上传 web166-170
  • Jest进阶知识:深入测试 React Hooks-确保自定义逻辑的可靠性
  • EHOME视频平台EasyCVR萤石设备视频接入平台视频诊断技术可以识别哪些视频质量问题?
  • 使用 MONAI Deploy 在 AMD GPU 上进行全身分割
  • VisionPro —— CogPatInspectTool对比工具
  • 基于uniapp和java的电动车智能充电系统软件平台的设计
  • html checkbox和label 文字不对齐解决办法
  • 某华迪加现场大屏互动系统mobile.do.php任意文件上传
  • windows安装mysql
  • Android 依赖统一配置管理(Version Catalogs)
  • 学习党的二十大精神,推动科技创新和发展
  • Spring中的资源Resource 以及分类(多种资源的实现类)
  • Follow软件的使用入门教程
  • PostgreSQL 字段按逗号分隔成多条数据的技巧与实践 ️
  • ClickHouse创建账号和连接测试
  • 【LeetCode】【算法】338. 比特位计数
  • TS-AWG控制电光调制器:推动科技应用新发展的利器
  • 一个.NET开源、轻量级的运行耗时统计库 - MethodTimer
  • Allegro: 开源的高级视频生成模型
  • 服务器的配置复杂,租用时该如何选择参数?
  • 数据库->索引
  • 入门车载以太网(3) -- 网络层
  • 核心概念解析Caffeine 缓存模型与策略
  • 在函数 \( f(x+1) = x^2 + 1 \) 中,\( x \) 和 \( x+1 \) 代表不同的概念
  • ElasticSearch认识