Solved

Questin about #define use

Posted on 2004-04-27
9
581 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 10934399
#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
ID: 10934556
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
ID: 10934596
Are you linking with uuid.lib and the MAPI libs?
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 5

Author Comment

by:jjacksn
ID: 10934924
Yeah, I'm linked to mapi32.lib and uuid.lib

why is their an underscore infront of the var name?
0
 
LVL 30

Expert Comment

by:Axter
ID: 10935038
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
ID: 10935046
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
ID: 10935577
I do that the latest SDK updates installed.
0
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
ID: 10937412
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
ID: 10950953
Alex, I'm pretty sure that's it, I'll be back in the office on Monday to check it out.
0

Featured Post

[Webinar] How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them. Thursday, July 13, 2017 10:00 A.M. PDT

Question has a verified solution.

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

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…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

729 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