Bootstrap

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文件和对应的导入库文件。#ifdef MFCLIBRARY1_EXPORTS
    #define MFCLIBRARY1_API __declspec(dllexport)
    #else
    #define MFCLIBRARY1_API __declspec(dllimport)
    #endif
  • 注意:MFCLIBRARY1_EXPORTS,是这个宏要放进去
;