how to solve the multi-defination when merge two program

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

turbot_yuAsked:
Who is Participating?
 
itsmeandnobodyelseCommented:
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
 
balderCommented:
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
 
AlexFMCommented:
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
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.

 
itsmeandnobodyelseCommented:
>>>> ?_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
 
rcarlanCommented:
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
 
itsmeandnobodyelseCommented:
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
 
rcarlanCommented:
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
 
itsmeandnobodyelseCommented:
>>>> 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
 
rcarlanCommented:
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
 
rcarlanCommented:
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
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.

All Courses

From novice to tech pro — start learning today.