以前, 不想暴露太多头文件时, 采用的方法: 把私有类成员声明成PVOID, 然后导出类实现中, 自己强转.
今天看到一个方法, 可以隐藏多余的头文件细节.
最终给DLL调出类调用者的文件有
MfcStdDllFrame.dll,
MfcStdDllFrame.lib,
MfcStdDllFrame_Export.h, 标准导出函数头文件
ClassExportA.h, 导出类头文件
比起以前的方法要好很多.
DLL调用者的代码:
// CallDllByStatic.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <afx.h> #include "MfcStdDllFrame_Export.h" #pragma comment(lib, "MfcStdDllFrame.lib") #include "ClassExportA.h" int main(int argc, char* argv[]) { int Rc = 0; int n = 74; CClassExportA ClassA; printf("隐式调用Dll/n"); Rc = ClassA.MethodX(n); printf("MfcStdDllFrame.dll's ClassA.MethodX(%d) = %d/n", n, Rc); printf("END/n"); getchar(); return 0; /** * 运行结果 * 隐式调用Dll MfcStdDllFrame.dll's ClassA.MethodX(74) = 272 END */ }
DLL提供者的代码:
//MfcStdDllFrame_Export.h //MFCSTDDLLFRAME_EXPORT_H #ifndef MFCSTDDLLFRAME_EXPORT_H #define MFCSTDDLLFRAME_EXPORT_H #ifdef MFCSTDDLLFRAME_EXPORT #define MFCSTDDLLFRAME_API __declspec(dllexport) #else #define MFCSTDDLLFRAME_API __declspec(dllimport) #endif MFCSTDDLLFRAME_API int __stdcall test(); #endif
// ClassExportA.h: interface for the CClassExportA class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_CLASSEXPORTA_H__B5117BFA_DDAC_4558_8490_EC5474D632C8__INCLUDED_) #define AFX_CLASSEXPORTA_H__B5117BFA_DDAC_4558_8490_EC5474D632C8__INCLUDED_ #include "MfcStdDllFrame_Export.h" #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 /** * 只声明类指针, 加上类前向声明, 就不用包含该头文件 */ class CClassB; class MFCSTDDLLFRAME_API CClassExportA : public CObject { DECLARE_DYNCREATE(CClassExportA) public: CClassExportA(); virtual ~CClassExportA(); INT MethodX(INT nIn); private: /** * 隐藏多余头文件的方法 * 只声明类指针, 加上类前向声明, 就不用包含该头文件 * * 以前我把不对外提供的内部类指针, 声明称PVOID * 在类实现的时候强转成对应的类, * * 新方法有点: 编码风格优雅, 简洁明了, 易于维护 */ CClassB * m_pClassB; }; #endif // !defined(AFX_CLASSEXPORTA_H__B5117BFA_DDAC_4558_8490_EC5474D632C8__INCLUDED_)
// ClassExportA.cpp: implementation of the CClassExportA class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MfcStdDllFrame.h" #include "ClassExportA.h" /** * 实现文件导出类的调用者是看不到的, * 可以包含各种内部的头文件 */ #include "ClassB.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNCREATE(CClassExportA, CCmdTarget) CClassExportA::CClassExportA() { m_pClassB = new CClassB; } CClassExportA::~CClassExportA() { delete m_pClassB; m_pClassB = NULL; } INT CClassExportA::MethodX(INT nIn) { return m_pClassB->Method(nIn + 'A'); }
// ClassB.h: interface for the CClassB class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_CLASSB_H__8D781CC6_8A94_4E2B_A3AA_9B80D7EB3387__INCLUDED_) #define AFX_CLASSB_H__8D781CC6_8A94_4E2B_A3AA_9B80D7EB3387__INCLUDED_ /** * 导出类的调用者看不到内部类的头文件 * 在内部头文件中, 可以包含各种内部的头文件 */ #include "ClassC.h" #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CClassB : public CObject { DECLARE_DYNCREATE(CClassB) public: CClassB(); virtual ~CClassB(); INT Method(INT nIn); private: CClassC * m_pClassC; }; #endif // !defined(AFX_CLASSB_H__8D781CC6_8A94_4E2B_A3AA_9B80D7EB3387__INCLUDED_)
// ClassB.cpp: implementation of the CClassB class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "ClassB.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNCREATE(CClassB, CObject) CClassB::CClassB() { m_pClassC = new CClassC; } CClassB::~CClassB() { delete m_pClassC; m_pClassC = NULL; } INT CClassB::Method(INT nIn) { return m_pClassC->Method(nIn + 'B'); }
// ClassC.h: interface for the CClassC class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_CLASSC_H__F8BA5D39_347E_4C5F_A38F_1E4BC7BB8441__INCLUDED_) #define AFX_CLASSC_H__F8BA5D39_347E_4C5F_A38F_1E4BC7BB8441__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 class CClassC : public CObject { DECLARE_DYNCREATE(CClassC) public: CClassC(); virtual ~CClassC(); INT Method(INT nIn); }; #endif // !defined(AFX_CLASSC_H__F8BA5D39_347E_4C5F_A38F_1E4BC7BB8441__INCLUDED_)
// ClassC.cpp: implementation of the CClassC class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "MfcStdDllFrame.h" #include "ClassC.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNCREATE(CClassC, CObject) CClassC::CClassC() { } CClassC::~CClassC() { } INT CClassC::Method(INT nIn) { return nIn + 'C'; }