• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1404
  • Last Modified:

DLL project make link error LNK2001 !

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
mike_marquet
Asked:
mike_marquet
  • 13
  • 9
  • 4
  • +1
1 Solution
 
BogdyPtrCommented:
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
 
ZoppoCommented:
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
 
mike_marquetAuthor Commented:
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
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

 
mike_marquetAuthor Commented:
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
 
mike_marquetAuthor Commented:
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
 
ZoppoCommented:
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
 
BogdyPtrCommented:
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
 
mike_marquetAuthor Commented:
To Zoppo & BogdyPtr :

It's the same.
0
 
ValiHCommented:
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
 
BogdyPtrCommented:
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
 
mike_marquetAuthor Commented:
To BogdyPtr :

Yes I have this code
0
 
mike_marquetAuthor Commented:
To ValiH :

It's the same.
0
 
ValiHCommented:
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
 
BogdyPtrCommented:
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
 
BogdyPtrCommented:
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
 
mike_marquetAuthor Commented:
I'm using MFC extension DLLs
0
 
ValiHCommented:
for: BogdyPtr
  Ne cunoastem sau mi-ai citit profile-ul?
0
 
BogdyPtrCommented:
for ValiH

  Am citit profilu'.
0
 
BogdyPtrCommented:
for ValiH

  Am citit profilu'.
0
 
ValiHCommented:
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
 
BogdyPtrCommented:
for ValiH

  Am citit profilu'.
0
 
BogdyPtrCommented:
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
 
BogdyPtrCommented:
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
 
BogdyPtrCommented:
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
 
BogdyPtrCommented:
Get rid of that AFX defines and undefines; u don't need them.
0
 
mike_marquetAuthor Commented:
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
 
mike_marquetAuthor Commented:
But the other project (CExExButton) will link notmally yet.

Why ?
0
 
BogdyPtrCommented:
I don't know. But if it works ...

:)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

  • 13
  • 9
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now