Re: Can't get static SolidBrush to initialize... what am I missing
"Stick" <Stick@discussions.microsoft.com> wrote in message
news:E788B357-0F2B-4AD7-AE64-CDAF6C52C504@microsoft.com
John,
"John Carson" wrote:
Where
Helpers::GDIPlusManager* pGdipm = new Helpers::GDIPlusManager();
appears in relation to any function is irrelevant. All that matters
is where it appears in relation to your definition of the static
brushes:
SolidBrush Cdu::brush_Mfd_Blk( Color(255, 0, 0, 0));
etc.
I was just trying to indicate that as it is at file scope in the .cpp
that instantiates the Cdu class object, that it would be before the
static Solidbrush.
That is wrong on two counts. First, the instantiation of a Cdu object does
*not* cause its static variables to be initialized. Second, where a function
is defined has no effect on the order of initialization, even of those
things that are initialized by the function. See below.
Unfortunately, I limited in that I am in a .dll, and have to
interfact to .c code. So, at this point as there is only one Cdu
instantiated anyway, I'm just going to try to use class vars to
simplify things.
I don't think use of a dll makes any difference. It is just a matter
of getting an instance of the GDIPlusManager instantiated in the
*same* .cpp file as the one that defines the static brushes and
*earlier* in the file than the definition of the static brushes.
Hmmm.... so if I understand you correctly, the GDI+ Init stuff must be
called within each .cpp that uses GDI+ calls? Strange then that this
works at all, as I have that Gdipm class in it's own .cpp file.
No. The way it works is as follows.
1.
Any statements at namespace/file scope that define variables are executed
first (so constructors are called, etc.). Within any given file, these
statements are executed in the order in which they appear. Thus if you have:
Helpers::GDIPlusManager* pGdipm = new Helpers::GDIPlusManager();
SolidBrush Cdu::brush_Mfd_Blk( Color(255, 0, 0, 0));
in the same file in the order shown, then pGdipm must be initialized before
Cdu::brush_Mfd_Blk.
By contrast, the order of initialization across files is unspecified. Thus
if you have
Helpers::GDIPlusManager* pGdipm = new Helpers::GDIPlusManager();
in one file and
SolidBrush Cdu::brush_Mfd_Blk( Color(255, 0, 0, 0));
in another file, then either could be executed first. This is the "static
initialization order fiasco" that I referred to in my first post.
http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.15
Accordingly, you should not have two variables at namespace/file scope in
different files if the order of initialization of the two variables matters.
(The link offers a workaround.)
Accordingly, my comments on putting things in one file are not because the
GDI+ initialization stuff needs to be done more than once; it is because you
cannot control the order of initialization if the variables are in different
files.
2.
After the execution of the code defining variables at namespace/file scope,
the main/WinMain function is entered and, eventually, exited. Thus any
variable at namespace/file scope will be initialized by the time you get to
main/WinMain.
3.
After main/WinMain has exited, destructors are called for the variables
defined at namespace/file scope in the reverse order to that in which the
constructors were called.
Note that where any function is defined is irrelevant as far as the order of
initialization is concerned, because defining a function does not cause any
initialization. Any initialization associated with a function (e.g., for
variables declared inside that function) occurs when that function is
*called*, not when it is defined. Usually functions are called inside
main/WinMain because you are not allowed to make a "naked" function call
anywhere else. The only function calls you can make at namespace/file scope
are those associated with the definition of a variable (i.e., constructor
calls and the calling of functions that return a variable that is used to
initialize a variable that is being declared).
--
John Carson