?
Solved

how to solve the multi-defination when merge two program

Posted on 2005-04-19
10
Medium Priority
?
363 Views
Last Modified: 2008-02-01
Hi Experts,

how to solve the multi-defination when merge two program.
The error message is below,

ServerSocketDlg.obj : error LNK2005: "protected: static struct AFX_MSGMAP const * __stdcall CAboutDlg::_GetBaseMessageMap(void)" (?_GetBaseMessageMap@CAboutDlg@@KGPBUAFX_MSGMAP@@XZ) already defined in pqhubDlg.obj

I cannot find the function of GetBaseMessageMap by search.

Thanks and Regards,

Turbot

0
Comment
Question by:turbot_yu
10 Comments
 
LVL 3

Assisted Solution

by:balder
balder earned 440 total points
ID: 13813943
Does a class in pqhubDlg.cpp inherit CAboutDlg?

It seems like CAboutDlg have been linked into this objectfile instead of "living" in its own objectfile/library.

Can you describe how CAboutDlg is beeing used in ServerSocketDlg and  pqhubDlg?
0
 
LVL 48

Assisted Solution

by:AlexFM
AlexFM earned 200 total points
ID: 13813970
Possibly both merged programs have their own CAboutDlg class. This class is created by MFC Application Wizard in main cpp file. I don't think that you need both of them in final application, you can remove one of these classes.
GetBaseMessageMap is internal static function used by MFC CWnd-derived classes. Since CAboutDlg class is defined in cpp and not h file, there is no names collision in compilation, but there are linker problems.
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 680 total points
ID: 13813985
>>>> ?_GetBaseMessageMap

That function was implemented by the BEGIN_MESSAGEMAP macro.

>>>> error LNK2005

The error was cause you have two impementations of class CAboutDlg - most likely by copying the Wizard generated cpp file from serversocketdlg.cpp to pqhubdlg.cpp or vice versa. Only one of them should contain implementation of CAboutDlg.

Regards, Alex


0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 9

Assisted Solution

by:rcarlan
rcarlan earned 680 total points
ID: 13814823
Take all header files from one of the programs and wrap the declarations in “namespace prog1 { }”. In all implementation files (.cpp) of this program, add “using namespace prog1;” at the top (after all “#include” lines).

Do the same for the second program – use a different namespace (e.g. prog2).

This should take care of any name collisions.

Radu

0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 680 total points
ID: 13814976
rcarlan,

_GetBaseMessageMap and CAboutDlg came from Wizard generated implementation code. Generally, one MFC project may contain only one implementation of CAboutDlg.

The asker copied the second cpp file - say pqhubdlg - from serversocketdlg or vice versa, removed class definition and implementation of class CAboutDlg *but* forgot to remove the following sequence

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
      //{{AFX_MSG_MAP(CAboutDlg)
            // No message handlers
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

The dialog class gets some message handling functionalities by that. However, the sequence must be defined only once.

turbot,

remove all code regarding CAboutDlg from the dialog that is *not* the main dialog.

Regards, Alex


0
 
LVL 9

Assisted Solution

by:rcarlan
rcarlan earned 680 total points
ID: 13815084
A project can contain any number of CAboutDlg classes. The key is to insulate them from one another by placing them in different namespaces. You can have prog1::CAboutDlg and prog2::CAboutDlg, by doing this:

namespace prog1
{

class CAboutDlg : public CDialog
{
//...
};

}

namespace prog2
{

class CAboutDlg : public CDialog
{
//...
};

}

In the two implementation files, you can use:

using namespace prog1;

// prog1::CAboutDlg implementation


and


using namespace prog2;

// prog2::CAboutDlg implementation


I understand the reason behind the linker error Turbot has reported. And I do appreciate that one About dialog is quite enough. I was just presenting a generic solution to the problem - just in case there may be other clashes between classes from the two programs.

Radu
0
 
LVL 39

Assisted Solution

by:itsmeandnobodyelse
itsmeandnobodyelse earned 680 total points
ID: 13815177
>>>> A project can contain any number of CAboutDlg classes.

Sorry, but MFC macros are not compatible with C++ namespaces. k Even, if it would compile and link (I have doubt's cause message maps contain class member function pointers, that were casted to baseclass member function pointers), it makes no sense as a Windows application has only one About... dialog.

Regards, Alex
0
 
LVL 9

Assisted Solution

by:rcarlan
rcarlan earned 680 total points
ID: 13815345
Whatever...
I was talking about a generic approach; you keep banging about CAboutDlg (no pun intended).

First of all:
>>"Sorry, but MFC macros are not compatible with C++ namespaces."
Try it before discounting it. The MFC macros couldn't care less about whether or not they are used in conjunction with namespaces.

Secondly:
>>"I have doubt's cause message maps contain class member function pointers, that were casted to baseclass member function pointers"
Yes, the message maps do store method pointers and casts to base are involved, but this has nothing to do with namespaces.

The compiler will deal with all these happily. The only one that will get confused is Class Wizard - but this will not impact on the program's functionality.

Lastly:
>>"it makes no sense as a Windows application has only one About... dialog"
This where I agree. But, as I said, as was offering a generic solution (for other potential clashes).

Radu

0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 680 total points
ID: 13815696
Radu,

you are right, it compiles and works ... though still not senseful in that case.

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
namespace XXX
{
class CAboutDlg : public CDialog
{
public:
      CAboutDlg();

// Dialog Data
      //{{AFX_DATA(CAboutDlg)
      enum { IDD = IDD_ABOUTBOX };
      //}}AFX_DATA

      // ClassWizard generated virtual function overrides
      //{{AFX_VIRTUAL(CAboutDlg)
      protected:
      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
      //}}AFX_VIRTUAL

// Implementation
protected:
      //{{AFX_MSG(CAboutDlg)
      //}}AFX_MSG
      DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
      //{{AFX_DATA_INIT(CAboutDlg)
      //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
      CDialog::DoDataExchange(pDX);
      //{{AFX_DATA_MAP(CAboutDlg)
      //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
      //{{AFX_MSG_MAP(CAboutDlg)
            // No message handlers
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

};

using namespace XXX;

>>>> The only one that will get confused is Class Wizard

Not at all, as it only looks for  //{{AFX and //}}AFX

Regards, Alex
0
 
LVL 9

Assisted Solution

by:rcarlan
rcarlan earned 680 total points
ID: 13815828
Class Wizard will not show two classes having the same name. If it's only one class and it's placed within a namespace, that's OK. But if you add a second class with the same name and put it in a different namespace, you can't get the two to both show up in Class Wizard (at least I couldn't find a way). This however will not impact on runtime functionality.

Radu
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

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

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

864 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