From: David Ching on 7 Jan 2010 16:41 "MFDonadeli" <hworking(a)gmail.com> wrote in message news:e1bc0977-5580-4cfb-a2c1-f8f24a2a7efb(a)34g2000yqp.googlegroups.com... > With project dependencies, I can access all the classes and functions > on this DLL, and in the build line command the lib apper at the end of > the command. > > And I think that if project dependencies is wrong the solution that I > describe, wouldn't compile: > Joe and the others are incorrect. Using Project Dependencies *does* in fact cause a link of the associated .lib file. You _do not_ have to add the .lib manually to the linker input. Now your original code: > //header file: SingleTon.h > class AFX_EXT_CLASS CMySingleton > { > public: > static CMySingleton* Instance() > { > if(!singleton) > singleton = new CMySingleton(); > return singleton; > } > > int a; > > // Other non-static member functions > private: > CMySingleton() {}; // Private > constructor > CMySingleton(const CMySingleton&); // Prevent copy- > construction > CMySingleton& operator=(const CMySingleton&); // Prevent > assignment > virtual ~CMySingleton() {}; > > static CMySingleton* singleton; > }; Well, you are declaring but not defining a (CMySingleton *) with static CMySingleton* singleton; This must have been done in SinglTon.cpp. But the import lib for your DLL doesn't export it. Hmm... have you checked that the compile options for your singleton extension DLL has the _AFXDLL and _USRDLL switches set correctly? BTW, what is the "int a"? Is that a typo? > In this case I can access the Singleton if I remove the variable > static CMySingleton* singleton and put on the Instance function like > this: > static CMySingleton* Instance() > { > static CMySingleton* singleton; > if(!singleton) > singleton = new CMySingleton(); > return singleton; > } > but the problem in this case, is that this function create another > instance of CMySingleton, even if static singleton var is already > initialized. This should work OK if you initialize as follows: static CMySingleton* Instance() { static CMySingleton* singleton = NULL; // <-- must set NULL!! if(!singleton) singleton = new CMySingleton(); return singleton; } -- David
From: Joseph M. Newcomer on 7 Jan 2010 18:07 Note that a true Singleton class is managed exclusively by its component. That is, if you have a DLL, the only instance of the singleton MUST be created by the DLL. The class cannot be instantiated in more than one DLL, nor can it be managed by the application. The example below is particularly bad, because it allows multiple instances of this function to exist, each one of which has its very own private static variable to hold what it thinks is the one-and-only instance. This would be wrong. The DLL that implements the singleton would create the instance. The use of DLLs is one of the dirty little secrets that none of the textbooks discuss, but the problem is intrinsic to the existence of DLLs in any environment (Windows, Mac OS X, Unix, linux, solaris, ...). To get a singleton class, the only reliable technique is to create a DLL that manages the singleton class and all clients of that class call this DLL. The naive model of singleton class assumes a single, uniform execution environment, and DLLs violate that naive assumption. joe On Thu, 7 Jan 2010 10:35:32 -0800 (PST), MFDonadeli <mfdonadeli(a)gmail.com> wrote: >Every function in this class works ok with project dependencies. > >In this case I can access the Singleton if I remove the variable >static CMySingleton* singleton and put on the Instance function like >this: > >static CMySingleton* Instance() > { > static CMySingleton* singleton; > if(!singleton) > singleton = new CMySingleton(); > return singleton; > } > > >but the problem in this case, is that this function create another >instance of CMySingleton, even if static singleton var is already >initialized. Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on 7 Jan 2010 18:13 See below... On Thu, 7 Jan 2010 11:01:45 -0800 (PST), MFDonadeli <hworking(a)gmail.com> wrote: >With project dependencies, I can access all the classes and functions >on this DLL, and in the build line command the lib apper at the end of >the command. *** No. You are definitely confused here. Your INCLUDE path allows your modules to locate the .h file that defines the class Your LIB path or explicit specification of the inclusion of the library are what make it visible to the linker. Note that when you have DLLs, you have to worry about all kinds of visibility issues of names; for example, you typically do not want to export a class that contains other than public methods (no data, no private methods). Often the way this is done is to have the exported class represent purely the public interface, and the DLL is always written in terms of a derived class that has the data and private/protected methods. But don't confuse "project dependency" with either "include path" or "linker specifications". They are not related. **** > >And I think that if project dependencies is wrong the solution that I >describe, wouldn't compile: **** Dependencies are unrelated. You can build a system with no specified dependencies which WILL successfully compile, but not in the right order. For example, if you change the DLL, and have not specified the dependencies, it is entirely reasonable for VS to compile and link your executable, and THEN discover that the DLL has also changed, and compile and link the DLL, which would be the wrong order. All dependencies do is establish compilation order; they do NOT create include paths or supply information to the linker. **** > >In this case I can access the Singleton if I remove the variable >static CMySingleton* singleton and put on the Instance function like >this: >static CMySingleton* Instance() > { > static CMySingleton* singleton; > if(!singleton) > singleton = new CMySingleton(); > return singleton; > } >but the problem in this case, is that this function create another >instance of CMySingleton, even if static singleton var is already >initialized. **** This is because this is not the correct implementation of a singleton class. joe **** Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Joseph M. Newcomer on 7 Jan 2010 18:14 I never had that happen. I always had to manually add it or I would get undefined symbol errors. joe On Thu, 7 Jan 2010 13:41:38 -0800, "David Ching" <dc(a)remove-this.dcsoft.com> wrote: >"MFDonadeli" <hworking(a)gmail.com> wrote in message >news:e1bc0977-5580-4cfb-a2c1-f8f24a2a7efb(a)34g2000yqp.googlegroups.com... >> With project dependencies, I can access all the classes and functions >> on this DLL, and in the build line command the lib apper at the end of >> the command. >> >> And I think that if project dependencies is wrong the solution that I >> describe, wouldn't compile: >> > >Joe and the others are incorrect. Using Project Dependencies *does* in fact >cause a link of the associated .lib file. You _do not_ have to add the .lib >manually to the linker input. > >Now your original code: > >> //header file: SingleTon.h >> class AFX_EXT_CLASS CMySingleton >> { >> public: >> static CMySingleton* Instance() >> { >> if(!singleton) >> singleton = new CMySingleton(); >> return singleton; >> } >> >> int a; >> >> // Other non-static member functions >> private: >> CMySingleton() {}; // Private >> constructor >> CMySingleton(const CMySingleton&); // Prevent copy- >> construction >> CMySingleton& operator=(const CMySingleton&); // Prevent >> assignment >> virtual ~CMySingleton() {}; >> >> static CMySingleton* singleton; >> }; > >Well, you are declaring but not defining a (CMySingleton *) with > > static CMySingleton* singleton; > > >This must have been done in SinglTon.cpp. But the import lib for your DLL >doesn't export it. Hmm... have you checked that the compile options for >your singleton extension DLL has the _AFXDLL and _USRDLL switches set >correctly? > >BTW, what is the "int a"? Is that a typo? > > > > >> In this case I can access the Singleton if I remove the variable >> static CMySingleton* singleton and put on the Instance function like >> this: >> static CMySingleton* Instance() >> { >> static CMySingleton* singleton; >> if(!singleton) >> singleton = new CMySingleton(); >> return singleton; >> } >> but the problem in this case, is that this function create another >> instance of CMySingleton, even if static singleton var is already >> initialized. > >This should work OK if you initialize as follows: > > static CMySingleton* Instance() > { > static CMySingleton* singleton = NULL; // <-- must set NULL!! > if(!singleton) > singleton = new CMySingleton(); > return singleton; > } > >-- David Joseph M. Newcomer [MVP] email: newcomer(a)flounder.com Web: http://www.flounder.com MVP Tips: http://www.flounder.com/mvp_tips.htm
From: David Ching on 7 Jan 2010 18:30
"Joseph M. Newcomer" <newcomer(a)flounder.com> wrote in message news:alqck591gias2lej7b560um35fus8qfq0i(a)4ax.com... >>Joe and the others are incorrect. Using Project Dependencies *does* in >>fact >>cause a link of the associated .lib file. You _do not_ have to add the >>.lib >>manually to the linker input. > I never had that happen. I always had to manually add it or I would get > undefined symbol > errors. > joe > I don't know what to say. I've been doing it this way for years. I just verified my .exe has Project Dependencies checkmark for a static lib, and the static lib is not mentioned in the .exe's Project Properties | Linker | Input | Additional Dependencies. -- David |