Linking in MFC Extension DLL's

Posted on 1997-09-29
Last Modified: 2013-11-20
Environment Visual C++ 5.0, NT 4.0

I am having trouble getting two MFC extension DLL's to link together. I have an extension DLL that contains a view and various functions and classes for that view. If I link this to an MFC EXE, all is fine.

However I want to link this to another MFC extension DLL that is then linked into an EXE. When I do this it fails to link correctly, giving the error:

--------------------Configuration: test2 - Win32 Debug--------------------
   Creating library Debug/test2.lib and object Debug/test2.exp
DibView.obj : error LNK2001: unresolved external symbol "public: static struct CRuntimeClass const  AZDIBVIEW::classAZDIBVIEW" (?classAZDIBVIEW@AZDIBVIEW@@2UCRuntimeClass@@B)
DibView.obj : error LNK2001: unresolved external symbol "protected: static struct AFX_MSGMAP const  AZDIBVIEW::messageMap" (?messageMap@AZDIBVIEW@@1UAFX_MSGMAP@@B)
Debug/test2.dll : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.

test2.dll - 3 error(s), 0 warning(s)

Is there a reason that I can not link two MFC extension DLL's together? The following extract is from the header file, and cpp file for the first extension DLL. the second extension DLL just adds a new class based on a CView (as with the EXE that I tested in originally) and then I replace CView with AZDIBVIEW.

The header of the first extension DLL is:

class AFX_EXT_CLASS AZDIBVIEW : public CView

friend class AZDRAWANNOTOOL;
friend class AZDRAWANNO;
friend class AZRECTANNOTOOL;
friend class AZDRAWRECT;

AZDIBVIEW();           // protected constructor used by dynamic creation

// These functions can be called from anywhere that has a pointer to the
view. They
// are used to control the image and the annotations used by the view.
Annotations are
// added through the document, and can be removed as a whole by the
document. Individual
// annotaions are removed by selecting and then removing from the view.
BOOL ToggleAnnoTips();
BOOL ToggleAnnotations();
void DeleteSelectedAnnos();
static void UpdateDIBViews();
void SetUserTool( AZTOOL tool );
void SetUserMode( AZMODE mode );
int GetZoomPercent();

// These are the overidable functions that should be called from your view.
virtual void GetViewMenu( CMenu&entA menu ) { popupviewmenu = FALSE; }
virtual void GetAnnoMenu( CMenu&nutA menu ) { popupannomenu = FALSE; }
virtual CSize GetImageSize();

virtual CDrawObjList* GetObjects() = 0;//{ return NULL; }
virtual void Remove( AZDRAWANNO* pObj ) = 0;//{;}
virtual AZDIB* GetDIBImage() = 0;//{ return NULL; }
virtual void DrawAnnotations( CDC* pDC ) = 0;//{;}
virtual AZDRAWANNO* ObjectAt( const CPoint&onsn point, AZDIBVIEW* pView ) =
0;//{ return NULL; };
virtual void Add( AZDRAWANNO* pObj ) = 0;//{;}

// ClassWizard generated virtual function overrides
virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD
dwStyle, const RECT&Name rect, CWnd* pParentWnd, UINT nID, CCreateContext*
pContext = NULL);
virtual void OnInitialUpdate();     // first time after construct
virtual void OnDraw(CDC* pDC);
virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView*

// Implementation
virtual ~AZDIBVIEW();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext&sEWV dc) const;

// Generated message map functions
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnUpdateZoomtool(CCmdUI* pCmdUI);
afx_msg void OnUpdateSelecttool(CCmdUI* pCmdUI);

// These functions and variables are for use within the class and by its
friend classes
// only. Don't tamper with them, you are likely to corrupt the image of the
DLL that is
// being used by your software, this will give serious bugs in your code.
virtual BOOL IsAnnotationsOn();

// functions for dealing with annotation tips
BOOL HoldUpAnno( CRect&nsOn position, CPoint point );
BOOL IsAnnoTipsOn();
void KillTimedTips();
void TimedTips( CPoint imagepoint, CPoint screenpoint );
void MoveTips(  CPoint imagepoint, CPoint screenpoint  );
void HideTips();
void DrawTips(  CPoint imagepoint, CPoint screenpoint  );

// functions for dealing with annotations and annotations list
AZDRAWANNO* GetLastAnnotation();
AZDRAWANNO* GetNextAnnotation( POSITION&ionA pos );
POSITION GetAnnotationHeadPos();
AZDRAWANNO* GetFirstAnnotation();
int SelectedAnnotations();
BOOL IsSelected( AZDRAWANNO* pObj );
BOOL CheckForObjectEdge( CRect rect );
void RemoveViewAnno( AZDRAWANNO* pObj );
void SelectWithinRect( CRect rect, BOOL bAdd );
void DeSelect( AZDRAWANNO* pObj );
void Select( AZDRAWANNO* pObj, BOOL bAdd = FALSE );
void InvalObj( AZDRAWANNO* pObj );

// functions for mapping between client and image space
void ClientToDoc( CPoint&Rect point );
void ClientToDoc( CRect&Rec rect );
void DocToClient( CPoint&Rect point, AZHANDLE pixel = CENTER );
void DocToClient( CRect&Rec rect, AZHANDLE pixel = CENTER );
BOOL ResetScrollBars( CPoint point );
void ClientToScrollValue( CPoint&llVa clientpoint );
void ScrollToClientValue( CPoint&ntVa clientpoint );
BOOL IsImageScrolled( UINT nBar );
SCROLLINFO GetScrollInfo( int nBar, UINT nMask = SIF_ALL );

// functions for dealing with zooming
void ZoomImage( CPoint point );
AZMODSIDE FindZoomSide( CRect zoomrect );

// functions for updating and drawing the client space
void ScrollDIB( UINT bar, UINT nSBCode, UINT nPos );
void UpdatePartialArea( CDC* pDC, CRect clientrect );
void UpdateClientArea( CDC* pDC, CRect clientrect, BOOL realimage =
BOOL IsActive();

// variables defined here

and then its corresponding cpp file includes the following lines. I have
removed any additional functions, as I guess they should not affect whether
the MSG_MAP can be resolved.



Thanks in advance,
Spencer Jones,
Azure Limited.
Question by:sdj
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 15

Expert Comment

by:Tommy Hui
ID: 1307127
When you link in an import library (which is what an extension DLL will produce as well as the .DLL), all that means to to the linker is, "if my target uses anything from this library, make a reference to it". But the important thing to remember is that the linker does not copy the import library into your target (otherwise, it defeats the purpose of DLLs). So your all-purpose extension DLL does not have a copy of the specialized extension DLL. And when you create your exe, you must specify all the import libraries it needs: In this case, both extension DLLs.

Author Comment

ID: 1307128
I'm not sure whether you misunderstood my question or I am missing the point of your answer? This works:

MFC EXTENSION (withview) -- MFC EXE (using view)

This does not:

MFC EXTENSION1 (with view) -- MFC EXTENSION2 (using view)

MFC EXTENSION2, includes the lib file for MFC EXTENSION1, as with the EXE example that *does* work. However MFC EXTENSION2 compiles but fails to link for the RUNTIME CLASS and MSG_MAP information. Everything else is linking fine. Why is the RUNTIME CLASS and MSG_MAP not being exported for MFC_EXTENSION2?

Accepted Solution

jaba earned 50 total points
ID: 1307129
The problem is with  AFX_EXT_CLASS macro.
This macro is defined by MFC as __declspec(dllexport) when the preprocessor symbols _AFXDLL and _AFXEXT are defined.
When you including first DLL include file to second MFC extention it macro EXPORTING class , not importing :-)
Because _AFXDLL and _AFXEXT also defined in second DLL project.

Solution is :
In the end of stdafx.h add :
// "MY" word different for different MFC extentions :-)
In your include file add:

#ifndef MY_EXT_CLASS
class MY_EXT_CLASS CMyExportingClass

this declaration exporting class when you inside class` project and importing in all other projects


Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

696 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question