![]() |
The MFC legacy code can use the managed extension classes or the function that uses the managed extension classes by making the derived class a new managed DLL (Dynamic Link Library). Just by incorporating the DLL, managed extension specific library class such as XML related class is freely available to unmanaged applications.
Suppose you have a class called CLabel and want to write
its contents in a file in XML format. You make a function such as
LoadXMLFile(char* fileName, CLabels* pLabels), which
needs to use the XMLTextWriter class. Since
XMLTextWriter class must be in a managed extension
project, you make it a managed extension DLL and try to call the
function -- and then here comes a problem. The main application needs
to pass CLabel class to the managed extension DLL.
In other words, to share the data structure from the main application to the managed extension DLL, another DLL must be shared. The figure below shows the DLL's and how they link the other modules. The arrows in the figure indicate the modules link the DLL modules that are pointed at by the arrows.
In the above example, the main application needs CLabel
class and it calls LoadXMLFile(char* fileName, CLabels*
pLabels).
The main application links to both managed extension DLL and the MFC DLL. The application includes the headers for the both modules.
#include "CLabel.h"
#include "LabelXML.h"
...
// Using CLabel class
CLabel* CLabelsDoc::GetLabel(int index)
{
CLabel* pLabel;
if(0<=index && index<GetArraySize())
pLabel=(CLabel*)m_labels.GetAt(index);
else
pLabel=new CLabel();
return pLabel;
}
// Calling LabelXML functions
void CLabelsDoc::LoadFile(CString fileName)
{
Initialize();
LoadLabelsFile(fileName.GetBuffer(), &m_labels, &m_fileName);
LoadImage(m_fileName);
}
...
The CLabel class defines the data structure for the whole
application. The class holds the data for a 'label', the caption, the
location, etc, and also the methods that are associated with a 'label'.
The header is shared with the DLL and the other modules. Therefore,
__declspec(import) or __declspec(import)
must be specified. In the header file shown below, the directive is
switched with DLLDIR_EXPORT. If the variable is set
before including the header file, the export directive will be set.
If not, the import directive will be set. The DLLDIR is
set to 'undefined' prior to the declaration, since other headers might
be using the variable. If you 'undefine' the variable, you can include
this for every other DLL headers.
#undef DLLDIR
#ifdef DLLDIR_EXPORT
#define DLLDIR __declspec(dllexport)
#else
#define DLLDIR __declspec(dllimport)
#endif
class DLLDIR CLabel
{
public:
CLabel(void);
~CLabel(void);
CPoint m_point;
CStringW m_label;
CString m_link;
CRect m_box;
COLORREF m_color;
CPtrArray m_lines;
int m_nLines;
void MoveLabel(CPoint newLocation);
double GetDistance(CPoint point);
double GetDistance(CPoint,CPoint,CPoint);
CPoint GetClosest(CPoint pos);
CPoint GetClosest(CPoint,CRect);
BOOLEAN IsOnLine(CPoint,CPoint,CPoint);
BOOLEAN IsOnLine(CPoint);
void SetLabel(LPWSTR str);
};
LabelXML module is the managed extension DLL. This DLL
must import the CLabel DLL module. This DLL in turn to
be linked to the main application module which calls the
LoadLabelsFile() and SaveLabelsFile().
The header must be shared in the same manner as the
CLabel class header.
#undef DLLDIR
#ifdef DLLDIR_EXPORT
#define DLLDIR __declspec(dllexport)
#else
#define DLLDIR __declspec(dllimport)
#endif
extern "C" DLLDIR int LoadLabelsFile(char* fileName, CPtrArray* pArray, CStringW* pImageFileName);
extern "C" DLLDIR int SaveLabelsFile(char* fileName, CPtrArray* pArray, CStringW* pImageFileName);
With the managed extension DLL and MFC DLL that defines the data
structure, the legacy MFC application can access to the functions that
instantiate managed extension classes and successfully uses their
methods. This article describes a CLabel example that
contains the managed extension DLL and MFC DLL and how the DLL should
be linked and specified.