Solved

Questin about #define use

Posted on 2004-04-27
9
577 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
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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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 viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

808 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