Solved

Questin about #define use

Posted on 2004-04-27
9
572 Views
Last Modified: 2010-08-05
In this source code:

http://support.microsoft.com/?kbid=171907

what is the effect of the lines

#define INITGUID


#define USES_IID_IMessage
0
Comment
Question by:jjacksn
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
#define INITGUID

tells the compiler to pull in the actual variable definitions for the GUIDS used. Since the declarations can and in fact are used over many compilation units (aka .cpp files), reserving space for them in each of them would be a waste of memory and - even worse - result in a linker error about multiply defined symbols. So, only one .cpp file will define that, and additionaly it has to be ensured that at least one does. 'USES_IID_IMessage' serves the same purpose.
0
 
LVL 5

Author Comment

by:jjacksn
Comment Utility
I see, thanks.  I'm unfourtunately getting compilation errors:

OutlookCOM error LNK2001: unresolved external symbol _CLSID_MailMessage
OutlookCOM error LNK2001: unresolved external symbol _IID_IMessage

Where CLSID_MailMessage is defined in that source code as

DEFINE_GUID(CLSID_MailMessage,
0x00020D0B,
0x0000, 0x0000, 0xC0, 0x00, 0x0, 0x00, 0x0, 0x00, 0x00, 0x46);

in mapiguid.h there is the code

#if !defined(INITGUID) || defined(USES_IID_IMessage)
DEFINE_OLEGUID(IID_IMessage,            0x00020307, 0, 0);

Both of the macros DEFINE_GUID and DEFINE_OLEGUID are called at the tope of my .cpp source file These vars are then referenced inside a class method in the same .cpp file.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Are you linking with uuid.lib and the MAPI libs?
0
 
LVL 5

Author Comment

by:jjacksn
Comment Utility
Yeah, I'm linked to mapi32.lib and uuid.lib

why is their an underscore infront of the var name?
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 
LVL 30

Expert Comment

by:Axter
Comment Utility
The compiler adds an underscore to the name when its trying to look for unresoved external symbols.

Have you downloaded the latest SDK?

You may be getting this error because you don't have the latest SDK loaded.

You can get the latest SDK free from MS web site.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
You can download the latest platform SDK from the following link:
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
0
 
LVL 5

Author Comment

by:jjacksn
Comment Utility
I do that the latest SDK updates installed.
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
Comment Utility
See the answer to

http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_20970112.html

Maybe, it already answers your question sufficiently, but i will try to give some more details:

In system header objbase.h there is the following code sequence

//-------------------------------------------------------------------------------------
#ifndef INITGUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
    EXTERN_C const GUID FAR name
#else

#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
        EXTERN_C const GUID name \
                = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }
#endif // INITGUID
//------------------------------------------------------------------------------------------

You could see, that there are two different definitions of the macro DEFINE_GUID dependend on the definition of the macro INITGUID. IF INITGUID is defined with DEFINE_GUID you only declare an extern variable. An extern variable can be used in a C or C++ variable as any other global variable however the linker expects that there is exactly an object module where the variable not only is declared as extern but defined, that means that a storage is assigned to that variable. In objbase.h the first definition declares the variable as extern and the second definition defines it (in the #else branch). Therefore in your project there must be exactly one CPP file that includes objbase.h while INITGUID isn't defined. All other CPP files _MUST_ have a #define INITGUID if  using macro DEFINE_GUID or DEFINE_OLEGUID before including any system headers. Otherwise, you would get a linker error that the variable _CLSID_MailMessage is duplicate defined.

Look at that comment that is in objbase.h above that definitions:

//------------------------------------------------------------------------------------------
// macros to define byte pattern for a GUID.
//      Example: DEFINE_GUID(GUID_XXX, a, b, c, ...);
//
// Each dll/exe must initialize the GUIDs once.  This is done in one of
// two ways.  If you are not using precompiled headers for the file(s) which
// initializes the GUIDs, define INITGUID before including objbase.h.  This
// is how OLE builds the initialized versions of the GUIDs which are included
// in ole2.lib.  The GUIDs in ole2.lib are all defined in the same text
// segment GUID_TEXT.
//
// The alternative (which some versions of the compiler don't handle properly;
// they wind up with the initialized GUIDs in a data, not a text segment),
// is to use a precompiled version of objbase.h and then include initguid.h
// after objbase.h followed by one or more of the guid defintion files.

//------------------------------------------------------------------------------------------

What i mean to be able to learn from that comment is that for a Wizard defined project that uses Precompiled Header Files, the include file stdafx.h does the job for you by defining INITGUID. However, i couldn't spot from this, where the GUIDs get defined.

Hope that helps,
Alex
 
0
 
LVL 5

Author Comment

by:jjacksn
Comment Utility
Alex, I'm pretty sure that's it, I'll be back in the office on Monday to check it out.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
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 technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

763 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

12 Experts available now in Live!

Get 1:1 Help Now