digitalmars.D.learn - Factory design
- John C (48/48) May 28 2006 So I've got an abstract class with a factory method. Users call the
- Jarrett Billingsley (4/6) May 28 2006 Did you try just putting "extern" (or "extern(D)") in front of both the
- John C (3/15) May 28 2006 I did - I get the same linking errors.
- Jarrett Billingsley (10/11) May 28 2006 Ohhhh yeah. I ran into the same thing on another thread about 15 down f...
- Ameer Armaly (5/17) May 28 2006 I agree. Perhaps with some sort of marker to designate them as
- Carlos Santander (4/76) May 28 2006 --
So I've got an abstract class with a factory method. Users call the factory method to instantiate an instance. It calls a function which modules that contain the contrete class must implement. But I'm getting linking errors. OptLink thinks 'createXmlReaderImpl' is undefined, presumably because it's expecting the body to be contained in the same module. Note that if 'createXmlReaderImpl' is declared with 'extern(C)', then it links without errors. I've seen a similar technique used before. The main entry point in dmain.d in phobos, for example. Ideas? module model; // Modules containing the concrete class implement this. XmlReader createXmlReaderImpl(Stream input); abstract class XmlReader { static XmlReader create(Stream input) { return createXmlReaderImpl(input); } // Abstract methods... } // impl1 implementation wraps some C library. module impl1; import model; XmlReader createXmlReaderImpl(Stream input) { return new XmlReaderImpl(input); } class XmlReaderImpl : XmlReader { // Implements XmlReader's abstract methods private this(Stream input) ... } // impl2 implementation wraps some other C library. module impl2; import model; XmlReader createXmlReaderImpl(Stream input) { return new XmlReaderImpl(input); } class XmlReaderImpl : XmlReader { // Implements XmlReader's abstract methods private this(Stream input) ... } // User code that chooses which implementation to use. module program; import model, impl1; // Choosing impl1 void main() { Stream s = ...; XmlReader reader = XmlReader.create(s); } Thanks, John.
May 28 2006
"John C" <johnch_atms hotmail.com> wrote in message news:e5ddb1$17kq$1 digitaldaemon.com...Note that if 'createXmlReaderImpl' is declared with 'extern(C)', then it links without errors.Did you try just putting "extern" (or "extern(D)") in front of both the prototype and the definition?
May 28 2006
Jarrett Billingsley wrote:"John C" <johnch_atms hotmail.com> wrote in message news:e5ddb1$17kq$1 digitaldaemon.com...I did - I get the same linking errors. extern(C) works because the name of the function doesn't get mangled.Note that if 'createXmlReaderImpl' is declared with 'extern(C)', then it links without errors.Did you try just putting "extern" (or "extern(D)") in front of both the prototype and the definition?
May 28 2006
"John C" <johnch_atms hotmail.com> wrote in message news:e5dgdt$1as6$1 digitaldaemon.com...extern(C) works because the name of the function doesn't get mangled.Ohhhh yeah. I ran into the same thing on another thread about 15 down from this one.. This is a real problem. Mangling function names with module names is a good idea on the surface, but it makes it impossible to declare a function in one module and define it in another without some ugly hacks and serious restrictions. Something needs to be done to solve this, such as not mangling module names into the names of functions which are declared "extern."
May 28 2006
"Jarrett Billingsley" <kb3ctd2 yahoo.com> wrote in message news:e5dju8$1dol$1 digitaldaemon.com..."John C" <johnch_atms hotmail.com> wrote in message news:e5dgdt$1as6$1 digitaldaemon.com...I agree. Perhaps with some sort of marker to designate them as module-independent if you will; you would be saying with extern that this function is meant to be declared anywhere.extern(C) works because the name of the function doesn't get mangled.Ohhhh yeah. I ran into the same thing on another thread about 15 down from this one.. This is a real problem. Mangling function names with module names is a good idea on the surface, but it makes it impossible to declare a function in one module and define it in another without some ugly hacks and serious restrictions. Something needs to be done to solve this, such as not mangling module names into the names of functions which are declared "extern."
May 28 2006
John C escribió:So I've got an abstract class with a factory method. Users call the factory method to instantiate an instance. It calls a function which modules that contain the contrete class must implement. But I'm getting linking errors. OptLink thinks 'createXmlReaderImpl' is undefined, presumably because it's expecting the body to be contained in the same module. Note that if 'createXmlReaderImpl' is declared with 'extern(C)', then it links without errors. I've seen a similar technique used before. The main entry point in dmain.d in phobos, for example. Ideas? module model; // Modules containing the concrete class implement this. XmlReader createXmlReaderImpl(Stream input);How about putting it in an abstract class, say a singleton?abstract class XmlReader { static XmlReader create(Stream input) { return createXmlReaderImpl(input); } // Abstract methods... } // impl1 implementation wraps some C library. module impl1; import model; XmlReader createXmlReaderImpl(Stream input) { return new XmlReaderImpl(input); } class XmlReaderImpl : XmlReader { // Implements XmlReader's abstract methods private this(Stream input) ... } // impl2 implementation wraps some other C library. module impl2; import model; XmlReader createXmlReaderImpl(Stream input) { return new XmlReaderImpl(input); } class XmlReaderImpl : XmlReader { // Implements XmlReader's abstract methods private this(Stream input) ... } // User code that chooses which implementation to use. module program; import model, impl1; // Choosing impl1 void main() { Stream s = ...; XmlReader reader = XmlReader.create(s); } Thanks, John.-- Carlos Santander Bernal
May 28 2006