Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Questin about #define use

Posted on 2004-04-27
9
Medium Priority
?
618 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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 2000 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

Independent Software Vendors: 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!

Question has a verified solution.

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

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
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.
Suggested Courses

564 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