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

_IID_INotification already defined (ATL COM)

I am trying to add an ATL simple object named as Notification to an ATL COM. Everything compiles fine but linking give the following error...

--------------------Configuration: TestCOM - Win32 Debug--------------------
Linking...
uuid.lib(ieguids.obj) : error LNK2005: _IID_INotification already defined in TestCOM.obj
uuid.lib(ieguids.obj) : warning LNK4006: _IID_INotification already defined in TestCOM.obj; second definition ignored
   Creating library Debug/TestCOM.lib and object Debug/TestCOM.exp
Debug/TestCOM.dll : fatal error LNK1169: one or more multiply defined symbols found
Error executing link.exe.

TestCOM.dll - 2 error(s), 1 warning(s)
-------------------------------------------------------------------------------------

Seems like there is already a symbol named as _IID_INotification in some uuid.lib. I can't exclude this lib as this contains many standard interfaces IID like _IID_IUnknown, _IID_IDispatch, _IID_IErrorInfo to name the few.

Is there a way around this other than not using name Notification?
0
amit_g
Asked:
amit_g
  • 5
  • 3
  • 2
  • +2
2 Solutions
 
jkrCommented:
You have to make sure to only once use

#define INITGUID
#include <initguid.h>
#include <objbase.h>
#endif

in your .cpp files.
0
 
amit_gAuthor Commented:
It is a standard ATL COM project. initguid.h is included only once and objbase.h is not included anywhere. That include has no effect. I could even comment it and the project still compiles.

#ifndef INITGUID
#include <initguid.h>
#endif

also did not make any difference. I still get linker error.

Also I don't think initguid.h and guiddef.h have anything to do with this error. The problem is due to symbol _IID_INotification defined in another lib. If I change Notification to anything else (say Notification1) the project compiles fine and links file. I am trying to find a way without renaming my interface.
0
 
novitiateCommented:
You are right. But I tried today the same thing, for me it didn't complain.

Test Env:
VC++ 6.0 with SP5
Windows XP - Professional with ie 6.0.2800

which version are you using. is MS .NET installed on your machine?


_novi_
0
NEW Veeam Agent for Microsoft Windows

Backup and recover physical and cloud-based servers and workstations, as well as endpoint devices that belong to remote users. Avoid downtime and data loss quickly and easily for Windows-based physical or public cloud-based workloads!

 
amit_gAuthor Commented:
I am using Visual Studio 6 for this project. I also have Visual Studio .Net and Visual Studio .Net 2003 on the same machine. I also have Win32 SDK installed. The machine has Window 2000 Pro as o/s. All products and the o/s have latest patches and service packs.
0
 
nonubikCommented:
You can try linking with /FORCE:MULTIPLE.

*BUT*, a file created with this option may not run as expected.
0
 
_ys_Commented:
Place your #include "<project_name>_i.c" in a namespace.

namespace MyNS
{
#include "<project_name>_i.c"
}
0
 
amit_gAuthor Commented:
nonubik, the project linked fine and worked fine with /FORCE:MULTIPLE probably because my .obj was being linked before ieguids.obj but as you have already mentioned, it might be risky. Also it gives tons of warnings.

_ys_, doing this I received many more unresolved symbols. Basically all IIDs and CLSIDs came out as undefined. They all have forward declarations in <project_name>.h that is generated from MIDL compiler, so can't be changed.
0
 
_ys_Commented:
> Basically all IIDs and CLSIDs came out as undefined

You'll have to qualify them with your namespace in order to use them.

void f ( )
{
    IID &systemIID = _IID_INotification;
    IID &yourIID = MyNS::_IID_INotification;
}
0
 
amit_gAuthor Commented:
That doesn't work because MyNS is undefined. Create a simple ATL COM yourself and name your interface as Notification. See if you could reproduce it and fix it by some method. If you cannot reproduce it, just use MyNS the way you have described and the linker would give errors. Suggest a way to fix those errors and I will use that in my project.
0
 
nonubikCommented:
I just took a look at MSDN' description for LNK2005 ('symbol' already defined). And they also suggest /FORCE:MULTIPLE :o)

"If you use uuid.lib in combination with other .lib files that define GUIDs (for example, oledb.lib and adsiid.lib). For example:
oledb.lib(oledb_i.obj) : error LNK2005: _IID_ITransactionObject
already defined in uuid.lib(go7.obj)
To fix, add /FORCE:MULTIPLE to the linker command line options, and make sure that uuid.lib is the first library referenced. "
0
 
_ys_Commented:
When you compile a type library there are two auto-generated file that your project uses:
- <project_name>_i.c
- <project_name>.h

If you abandon these (don't include them / exclude them from build), and simply #import the type library file your errors disappear.

The following code snippets are from my test project. Project name was Q_21380940, naturally.

-----------------<-----------------
// Q_21380940.cpp : Implementation of DLL Exports.

#include "stdafx.h"
#include "resource.h"

//<-->#include "Q_21380940.h"
#import "debug/Q_21380940.tlb" named_guids

class CQ_21380940Module : public CAtlDllModuleT< CQ_21380940Module >
{
public :
    DECLARE_LIBID(Q_21380940Lib::LIBID_Q_21380940Lib) //<-->
    DECLARE_REGISTRY_APPID_RESOURCEID(IDR_Q_21380940, "{D3D5CB94-6AC3-4584-BE61-08E9156291EF}")
};

// ... ommitted ...
-----------------<-----------------

-----------------<-----------------
// CoNotification.cpp : Implementation of CoNotification

#pragma once
#include "resource.h"       // main symbols

//<-->#include "Q_21380940.h"
#import "debug/Q_21380940.tlb" named_guids

// CoNotification

class ATL_NO_VTABLE CoNotification :
    public CComObjectRootEx<CComSingleThreadModel>,
    public CComCoClass<CoNotification, &Q_21380940Lib::CLSID_CoNotification>, //<-->
    public Q_21380940Lib::INotification //<-->
{
public:
// ... ommitted ...

BEGIN_COM_MAP(CoNotification)
    COM_INTERFACE_ENTRY(Q_21380940Lib::INotification) //<-->
END_COM_MAP()

// ... ommitted ...
};

OBJECT_ENTRY_AUTO(Q_21380940Lib::CLSID_CoNotification, CoNotification) //<-->
-----------------<-----------------

In short, replace all #include "Q_21380940.h" statements with #import "debug/Q_21380940.tlb" named_guids. And don't link with Q_21380940_i.c

The above solution infers that type libraries are compiled in a separate project. For a large project this is recommended due to increased cross-referencing. For a small project its overkill.
0
 
amit_gAuthor Commented:
nonubik's solution worked but I wasn't sure about the long term effects so did not use it.

_ys_'s solution seems to be the correct solution. However, it is too much for such a small problem.

Since I couldn't find any easier solution, I ended up renaming the IID :)

Thanks everyone.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 5
  • 3
  • 2
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now