Solved

DLL project make link error LNK2001 !

Posted on 2001-09-06
28
1,355 Views
Last Modified: 2013-11-20
Context :

2 projects that makes a DLL at output.

1st project exports a class (CExButton) derived from CButton

2nd project exports a class (CExExButton) derived from CExButton

1st project compiles at links with no errors.

2st project compiles OK but has an error at link process :

--------------------Configuration: CExExButton - Win32 Debug--------------------
Linking...
   Creating library Debug/CExExButtonD.lib and object Debug/CExExButtonD.exp
ExExButton.obj : error LNK2001: unresolved external symbol "protected: static struct AFX_MSGMAP const  CExButton::messageMap" (?messageMap@CExButton@@1UAFX_MSGMAP@@B)
Debug/CExExButtonD.dll : fatal error LNK1120: 1 unresolved externals
Error executing link.exe.

CExExButtonD.dll - 2 error(s), 0 warning(s)


DID SOMEONE HAS AN IDEA TO RESLOVE THIS PROBLEM !
0
Comment
Question by:mike_marquet
  • 13
  • 9
  • 4
  • +1
28 Comments
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6459857
Select second project, go to project/dependencies. Check the box in front of first project name.
Select first project, go to project/settings general tab . Set the output directory the same as the second project debug directory. Try to compile the projects. If still exists errors post the implementation of CExExButton ( the .cpp file )
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 6459860
Hi mike_marquet,

here's a short exceprt from MSDN article http://support.microsoft.com/support/kb/articles/Q128/1/99.asp

--------------------------
...you may run into an additional problem due to the fact that you are no longer exporting all members of the class. The problem is in the way that MFC macros work. Several of MFC's helper macros actually declare or define data members. Therefore, these data members will also need to be exported from your DLL.

For example, the DECLARE_DYNAMIC macro is defined as follows when building an extension DLL:

   #define DECLARE_DYNAMIC(class_name) \
   protected: \
     static CRuntimeClass* PASCAL _GetBaseClass(); \
   public: \
     static AFX_DATA CRuntimeClass class##class_name; \
     virtual CRuntimeClass* GetRuntimeClass() const; \  
The line that begins "static AFX_DATA" is declaring a static object inside of your class. To export this class correctly and access the run-time information from a client .EXE, you need to export this static object. Because the static object is declared with the modifier AFX_DATA, you only need to define AFX_DATA to be _declspec(dllexport) when building your DLL and define it as _declspec(dllimport) when building your client executable. As discussed above, AFX_EXT_CLASS is already defined in this way. So you just need to re-define AFX_DATA to be the same as AFX_EXT_CLASS around your class definition.

For example:

#undef  AFX_DATA
   #define AFX_DATA AFX_EXT_CLASS

   class CExampleView : public CView
   {

     DECLARE_DYNAMIC()
     // ... class definition ...

   };

   #undef  AFX_DATA
   #define AFX_DATA
MFC always uses the AFX_DATA symbol on data items it defines within its macros, so this technique will work for all such scenarios. For example it will work for DECLARE_MESSAGE_MAP.

NOTE: if you are exporting the entire class rather than selected members of the class, static data members are automatically exported.
--------------------------

hope that helps,

ZOPPO
0
 

Author Comment

by:mike_marquet
ID: 6459911
To BogdyPtr :

It is always done, a dependency is always set.

To Zoppo :

When I do this, I became error message :

--------------------Configuration: CExButton - Win32 Debug--------------------
Compiling...
ExButton.cpp
d:\cexbutton\exbutton.h(61) : error C2487: 'messageMap' : member of dll interface class may not be declared with dll interface
Error executing cl.exe.

CExButtonD.dll - 1 error(s), 0 warning(s)
0
 

Author Comment

by:mike_marquet
ID: 6459922
HERE'S THE HEADER OF CExButton :

#if !defined(AFX_EXBUTTON_H__0D5BD593_A177_11D5_A2DB_00400538BD6C__INCLUDED_)
#define AFX_EXBUTTON_H__0D5BD593_A177_11D5_A2DB_00400538BD6C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ExButton.h : header file
//
#include "..\CMyRgn\MyRgn.h"

/////////////////////////////////////////////////////////////////////////////
// CExButton window

#undef AFX_DATA
 #define AFX_DATA AFX_EXT_CLASS

class AFX_EXT_CLASS CExButton : public CButton
{
// Construction
public:
     CExButton();

// Attributes
public:

// Operations
public:

// Overrides
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CExButton)
     public:
     virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
     //}}AFX_VIRTUAL

// Implementation
public:
     virtual ~CExButton();

     // Generated message map functions
protected:
     //{{AFX_MSG(CExButton)
     afx_msg void OnCaptureChanged(CWnd *pWnd);
     afx_msg void OnMouseMove(UINT nFlags, CPoint point);
     afx_msg BOOL OnEraseBkgnd(CDC* pDC);
     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()
};

#undef AFX_DATA
 #define AFX_DATA

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_EXBUTTON_H__0D5BD593_A177_11D5_A2DB_00400538BD6C__INCLUDED_)
0
 

Author Comment

by:mike_marquet
ID: 6459930
HERE'S THE HEADER OF CExExButton :

#if !defined(AFX_EXEXBUTTON_H__2C0DAD2C_A243_11D5_A2DB_00400538BD6C__INCLUDED_)
#define AFX_EXEXBUTTON_H__2C0DAD2C_A243_11D5_A2DB_00400538BD6C__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <afxtempl.h>
// RgnColButton.h : header file
//
#include "..\CRgnButton\CRgnButton.h"

/////////////////////////////////////////////////////////////////////////////
// CExExButton window

class AFX_EXT_CLASS CExExButton : public CExButton
{
// Construction
public:
     CExExButton();

// Attributes
public:

// Operations
public:

// Overrides
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CExExButton)
     public:
     virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
     //}}AFX_VIRTUAL

// Implementation
public:
     virtual ~CExExButton();

     // Generated message map functions
protected:
     //{{AFX_MSG(CExExButton)
     //}}AFX_MSG

     DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_EXEXBUTTON_H__2C0DAD2C_A243_11D5_A2DB_00400538BD6C__INCLUDED_)
0
 
LVL 30

Expert Comment

by:Zoppo
ID: 6459961
The error 'd:\cexbutton\exbutton.h(61) : error C2487: 'messageMap' : member of dll interface class may not be declared' seems to have the reason that AFX_DATA is defined as AFX_EXT_CLASS and DECLARE_MESSAGE_MAP uses AFX_DATA (so AFX_EXT_CLASS) to declare 'messageMap' while
the class itself alread is declared as AFX_EXT_CLASS.

It's not possible to declare both a class and members from that class as __declspec( dllimport/dllexport ) (see help for C2487).

so, I think it may work if you simply do
#undef AFX_DATA
#define AFX_DATA
before
DECLARE_MESSAGE_MAP()

hope that helps,

ZOPPO
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6460052
Put a code like this in

#ifdef FIRSTDLLNAME_DLL
#define FIRSTDLLNAME_API __declspec(dllexport)
#else
#define FIRSTDLLNAME_API __declspec(dllimport)
#endif

go to project/settings for first dll and in C++ tab add to preprocesor definition FIRSTDLLNAME_DLL

change the line
>>class AFX_EXT_CLASS CExButton : public CButton
with
class AFX_EXT_CLASS FIRSTDLLNAME_API CExButton : public CButton

include this header in the header of the CExExButton class.

That shoud do it.

0
 

Author Comment

by:mike_marquet
ID: 6460084
To Zoppo & BogdyPtr :

It's the same.
0
 

Expert Comment

by:ValiH
ID: 6460121
Hi,
  I am not sure that this it will work, but if what the other guys teaches you doesn't, try this: in the project where you receive the error go to project settings, chose the Link tab and write the name of the dll that you are using.
  Please let me now if it works.
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6460127
Do u have this code in your cpp file of CExExButton
BEGIN_MESSAGE_MAP( CExExButton, CExButton )
 //{{AFX_MSG_MAP( CExExButton )
 //}}AFX_MSG_MAP
END_MESSAGE_MAP( )
?
0
 

Author Comment

by:mike_marquet
ID: 6460152
To BogdyPtr :

Yes I have this code
0
 

Author Comment

by:mike_marquet
ID: 6460155
To ValiH :

It's the same.
0
 

Expert Comment

by:ValiH
ID: 6460772
I remember that I had the same problem once and I solve it by adjusting the option from ?Project Settings?. Maybe you could send me the project thru e-mail? If you want that, send me a blank mail at vhaicu@hotmail.com in order to have your address and I will reply to you from the address that I use at the office.
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6460839
What kind of .dll project do u use.

Vali, uita-te la primu' comment care l-am pus. Daca faci setarile alea nu mai trebe sa specifici dll-ul la link.
0
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6460892
What kind of .dll project do u use.

Vali, uita-te la primu' comment care l-am pus. Daca faci setarile alea nu mai trebe sa specifici dll-ul la link.
0
 

Author Comment

by:mike_marquet
ID: 6460921
I'm using MFC extension DLLs
0
 

Expert Comment

by:ValiH
ID: 6460939
for: BogdyPtr
  Ne cunoastem sau mi-ai citit profile-ul?
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6461004
for ValiH

  Am citit profilu'.
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6461058
for ValiH

  Am citit profilu'.
0
 

Expert Comment

by:ValiH
ID: 6461213
BogdyPtr.
  Ce fain! Trimite-mi un mail pe vhaicu@hotmail.com ca sa am adresa ta si iti raspund de pe cea de la lucru ca sa nu o dau pe asta pe site. OK? E chiar fain sa imi raspunda cineva in romana pe site-ul asta!
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6461329
for ValiH

  Am citit profilu'.
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6461523
To ValiH:

Adresa mea e BogdyPtr@mailandnews.com . Acum nu stiu de ce nu vrea sa se conecteze la SMTP. Iti trimit mai tarziu si un mail.
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6461733
Go to File View , select first dll project, open it, select source files folder, open it, go to firstdllprojectname.def file and doubleclick it.
You sould see somethink like:

; 1.def : Declares the module parameters for the DLL.

LIBRARY      "1"
DESCRIPTION  '1 Windows Dynamic Link Library'

EXPORTS
    ; Explicit exports can go here

Add the following line at the end of file:

    ?messageMap@CExButton@@1UAFX_MSGMAP@@B

If does not work i'll be back.
0
 
LVL 2

Accepted Solution

by:
BogdyPtr earned 50 total points
ID: 6461765
Go to File View , select first dll project, open it, select source files folder, open it, go to firstdllprojectname.def file and doubleclick it.
You sould see somethink like:

; 1.def : Declares the module parameters for the DLL.

LIBRARY      "1"
DESCRIPTION  '1 Windows Dynamic Link Library'

EXPORTS
    ; Explicit exports can go here

Add the following line at the end of file:

    ?messageMap@CExButton@@1UAFX_MSGMAP@@B

If does not work i'll be back.
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6461774
Get rid of that AFX defines and undefines; u don't need them.
0
 

Author Comment

by:mike_marquet
ID: 6463090
When I add wath you say to the .def file, I have this warning :

--------------------Configuration: CExButton - Win32 Debug--------------------
Linking...
ExButton.obj : warning LNK4197: export "?messageMap@CExButton@@1UAFX_MSGMAP@@B" specified multiple times; using first specification
   Creating library Debug/CExButtonD.lib and object Debug/CExButtonD.exp
CExButtonD.exp : warning LNK4070: /OUT:CExButton.dll directive in .EXP differs from output filename "Debug/CExButtonD.dll"; ignoring directive
Copying Files ...
debug\CExButtonD.dll
        1 file(s) copied.
debug\CExButtonD.lib
        1 file(s) copied.

CExButtonD.dll - 0 error(s), 2 warning(s)
0
 

Author Comment

by:mike_marquet
ID: 6463091
But the other project (CExExButton) will link notmally yet.

Why ?
0
 
LVL 2

Expert Comment

by:BogdyPtr
ID: 6463247
I don't know. But if it works ...

:)
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

758 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now