paizza paizza - 3 months ago 15
C++ Question

How do you "declare" a global struct?

I've a .h file that declare 3 different/similar class:

#ifndef _ICUSTOMCONTROLS_
#define _ICUSTOMCONTROLS_

class ICustomKnob1 : public IKnobControl
{
private:
// ..

public:
// ..
};

class ICustomKnob2 : public IControl
{
private:
// ..

public:
// ..
};

class ICustomButton : public IButtonControl
{
private:
// ..

public:
// ..
};

#endif // !_ICUSTOMCONTROLS_


I've a cpp file that define these class. I include the .h in the cpp and also in other .h/.cpp files within the project (which is a DLL).

At this point, in the CPP, I'd like to use a common/global struct (
IText
) for all the 3 classes. If I add the declaration in the .h:

IText gTextCustomControl;


in fact it "define" it, so I got a
LNK1169 one or more multiply defined symbols found
error message on compiling (as I said, I add this .h many times).

I could add it (with real definition) in the .cpp file:

IText gTextCustomControl = IText(12, &COLOR_WHITE, "Arial", IText::kStyleBold, IText::kAlignCenter, 0, IText::kQualityDefault);


But I will never sure in the DLL when this will be "processed" (maybe later the CTOR of the classes? maybe more times, wasting resources?). I don't think is a good way.

I could add extern as well on .h and define it as above, but for security reason is even worse (someone could access from the "extern" to it).

How would you manage this situation? Or its not possible share a common struct across objects?

Answer

"Bt I will never sure in the DLL when this will be "processed" (maybe later the CTOR of the classes?"

This is indeed the correct concern. DLL globals will be constructed from DllMain, and DllMain is heavily restricted in what it can do. You can't load other DLL's from there (loader lock), or do anything that would force Windows to load other DLL's. So using functions from other DLL's is generally also banned (exception: if your A.DLL causes your B.DLL to be loaded, then B.DLL may call functions from A.DLL. ).

Correct solution:

IText& getTextCustomControl();
...
IText& getTextCustomControl() {
   static IText retval (12, &COLOR_WHITE, "Arial", IText::kStyleBold,
                 IText::kAlignCenter, 0, IText::kQualityDefault);
   return retval;
}

This initializes the object on the first call to getTextCustomControl, which in general will happen way after all DllMain() functions have finished.

Comments