I'm writing an ATL project and I wonder how should I create classes here.
Right now I have one class created by Add/Class/ATL Simple Object. I want to divide it to smaller classes but method from this classes should use CComPtr and have CComPtr as an argument. I can't create 'simple' c++ class because I don't have CComPtr there.
Should I create ATL classes by ATL Simple Object Wizard and then use interface for this class to call methods. Like here:
CComPtr<ITestAtlClass> tptr;
tptr.CoCreateInstance(CLSID_TestAtlClass);
tptr->test();
And should I add all public methods by Class View/ITestAtlClass/Add/Add Method?
What about constructors? Do I must initialize my class only by properties (and add them by Class View/ITestAtlClass/Add/Add Property)? And pass every com object by IUnknown interface?
Can somebody tell me how it should be done in ATL project. I will use this smaller classes internally (nobody will create this classes outside my DLL) just to make my code more readable.
I don't understand your comment that you can't use CComPtr from a simple C++ class. Can you please clarify?
I see two strategies:
build a clean C++ object model that solves the problem, and then wrap it in a thin facade layer of one or more COM objects
Use ATL classes throughout, and use CComObject<> and derivatives to instantiate and maintain these without the overhead of CoCreateInstance and the limitations of only using public interfaces.
The first one is usually much nicer, but if you're building a data-heavy object model, the second can be a useful technique.
If you have an ATL COM class called CVehicle, that derives from CComObjectRootEx<> and friends, you can instantiate it like so;
CComObject<CVehicle>* vehicle = NULL;
CComObject<CVehicle>::CreateInstance(&vehicle);
vehicle->AddRef();
// To get at any of its interfaces, use:
CComPtr<ICar> car = 0;
vehicle->QueryInterface(&car);
// And to delete object, use:
vehicle->Release();
There's also variations on CComObject<>, e.g. CComObjectStack<> that use different allocation and reference counting strategies.
As you can see, this is pretty messy. If you can explain what you mean by your comment on not being able to use CComPtr, maybe I can expand on that.
Related
We're interfacing to some 3rd party COM objects from a C++Builder 2010 application.
Currently we import the type library and generate component wrappers, and then are able to make method calls and access properties in a fairly natural way.
object->myProperty = 42;
object->doSomething(666);
However, we've been bitten by changes to the COM object's interface (which is still being extended and developed) causing our own app to fail because some method GUIDs seem to get invalidated - even if the only change to the interface has been the addition of a new method).
Late Binding has been suggested as a way of addressing this. I think this requires our code to be changed rather like this:
object.OlePropertySet("myProperty", 42);
object.OlePrcedure("doSomething", 666);
Obviously this is painful to read and write, so we'd have to write wrapper classes instead.
Is there any way of getting late binding wrappers generated automatically when we import the type library? And, if so, are they smart enough to only do the textual binding once when the object is created, rather than on every single method call?
When you import a TypeLibrary for a COM object that supports late-binding (when it implements the IDispatch interface), the importer can generate separate wrapper classes (not components) for both static-binding and late-binding.
Adding a new method to an existing interface should not invalidate your code. Methods do not have GUIDs. However, for an IDispatch-based interface, its methods do have DISPID values associated with them, and those DISPID values can be changed from one release to another. Though any respectable COM developer should never do that once an interface definition has been locked in.
After deep investigation of the code and headers generated by the TLIBIMP, this turns out to be fairly easy.
If your Type Library has a class Foo, then after importing the type library, you would typically use the auto-generated smart pointer classes IFooPtr.
{
IFooPtr f;
...
f->myMethod(1,2);
}
You should note that at this point that the bindings are static - that is, they depend not just on the GUIDs of the objects and the DISPIDs of the methods, but on the exact layout of the VTable in the DLL. Any changes that affect the vtable - for instance, adding an additional method to a base class of Foo will cause the method call to fail.
To use dynamic bindings, you can use the IFooDisp classes instead of IFooPtr. Again, these are smart wrappers, handling object lifetimes automatically. Note that with these classes you should use the . operator to access methods, not the indirection -> operator. Using the indirection operator will call the method, but via a static binding.
{
IFooDisp f;
...
f.myMethod(1,2);
}
By using these IDispatch-based wrappers, methods will be dispatched by their DISPIDs, even if the objects vtable layout is changed. I think these classes also give a way to dispatch by function name rather than DISPID, but haven't confirmed the details of that.
I am looking into DirectShow samples from Windows SDK. Many of the classes feature non-default constructor. How those constructors are called? Who supplies arguments?
Can I use those classes in C++ programs without registration? If so I could use class constructor directly.
If I use a COM class without registration what happens in the following code fragment:
Foo * foo = new Foo(.....); // note, not using CoCreateInstance
Bar * bar = foo->QueryInterface(...);
bar->Release();
delete foo; // CRASH?
Thank you!
It has nothing to do with COM, it is just the framework is built this way and constructor arguments in DirectShow BaseClasses are necessary to get everything together - the class, the ancestor, the instantiating factory.
Using COM class without registration might be or might not be possible. I suspect you might be interested in using DirectShow filter without registration instead, and there is a good article on the topic: Using Filters Without Registration.
A C++ class that's exposed as a real COM coclass cannot in general have a constructor that takes arguments. There's no mechanism for the COM client code to pass arguments to the CoCreateInstance() function. A COM interface typically has an Initialize() method to supply required initialization. Technically that can be doctored as well, CoCreateInstance is just a convenience function that hides the class factory (IClassFactory). A custom class factory with a custom CreateInstance() method is possible, but rarely done.
Microsoft uses the interface-based programming model that's common in COM code in non-COM code as well. DirectX is a good example. Think of Direct3DCreate9Ex() as the class factory.
I'm working in Visual Studio 2005 with a pure unmanaged project (C++). I have a COM class, from a third party, in a OCX file. This class is a control ("widget"). I've been using it through a IDispatch wrapper class generated using the Add Class from Typelib Wizard.
I would like to extend this class in a few ways and public inheritance would be way more practical than compositing (I want the derived object to expose every single method that the parent class does). The derived class should also be available as a COM component.
Can I do this? If positive, how can I accomplish this?
It is not possible to inherit from COM classes as you can in C++. There are workarounds though:
COM Aggregates
Forwarding
COM aggregates is only useful if you want to add an interface (with implementation) to an existing COM class. You cannot intercept calls to the aggregated object.
Forwarding means that if you have an interface IExistingInterface, you implement your own class that implements IExistingInterface. In your class you keep a reference to an instance of the object you want to "inherit" from. In your implementation of IExistingInterface, you forward calls as appropriate to the "inherited" object. This method gives you total control.
Example: (pseudo-code!)
class MyClass : IExistingInterface {
IExistingInterface* m_pInherited;
public:
MyClass() {
::CoCreateInstance(CLSID_OtherImplementation, ..., ..., IID_IExistingInterface, (void**)&m_pInherited);
}
// IExistingInterface methods
HRESULT MethodX() {
// Do some pre processing
HRESULT hr = m_pInherited->MethodX();
if(FAILED(hr))
return hr;
// Do some post processing
return S_OK;
}
};
Edit:
I really recommend that you use ATL to create your COM component. In that case, construct the "inherited" object in FinalConstruct() rather than the C++ constructor.
You can create a new interface that derives from the first. Your QueryInterface function will need to respond to both GUIDs and deliver the proper pointer. Once you've done that, have your concrete class implement the superset of the functions (i.e. all of the second interface, including everything inherited from the first.)
If your concrete class will also inherit from a concrete class in the library, you're going to have a diamond inheritance pattern. You can search for solutions to that, I'd start here: Diamond inheritance (C++)
I am relatively new to "design patterns" as they are referred to in a formal sense. I've not been a professional for very long, so I'm pretty new to this.
We've got a pure virtual interface base class. This interface class is obviously to provide the definition of what functionality its derived children are supposed to do. The current use and situation in the software dictates what type of derived child we want to use, so I recommended creating a wrapper that will communicate which type of derived child we want and return a Base pointer that points to a new derived object. This wrapper, to my understanding, is a factory.
Well, a colleague of mine created a static function in the Base class to act as the factory. This causes me trouble for two reasons. First, it seems to break the interface nature of the Base class. It feels wrong to me that the interface would itself need to have knowledge of the children derived from it.
Secondly, it causes more problems when I try to re-use the Base class across two different Qt projects. One project is where I am implementing the first (and probably only real implementation for this one class... though i want to use the same method for two other features that will have several different derived classes) derived class and the second is the actual application where my code will eventually be used. My colleague has created a derived class to act as a tester for the real application while I code my part. This means that I've got to add his headers and cpp files to my project, and that just seems wrong since I'm not even using his code for the project while I implement my part (but he will use mine when it is finished).
Am I correct in thinking that the factory really needs to be a wrapper around the Base class rather than the Base acting as the factory?
You do NOT want to use your interface class as the factory class. For one, if it is a true interface class, there is no implementation. Second, if the interface class does have some implementation defined (in addition to the pure virtual functions), making a static factory method now forces the base class to be recompiled every time you add a child class implementation.
The best way to implement the factory pattern is to have your interface class separate from your factory.
A very simple (and incomplete) example is below:
class MyInterface
{
public:
virtual void MyFunc() = 0;
};
class MyImplementation : public MyInterface
{
public:
virtual void MyFunc() {}
};
class MyFactory
{
public:
static MyInterface* CreateImplementation(...);
};
I'd have to agree with you. Probably one of the most important principles of object oriented programming is to have a single responsibility for the scope of a piece of code (whether it's a method, class or namespace). In your case, your base class serves the purpose of defining an interface. Adding a factory method to that class, violates that principle, opening the door to a world of shi... trouble.
Yes, a static factory method in the interface (base class) requires it to have knowledge of all possible instantiations. That way, you don't get any of the flexibility the Factory Method pattern is intended to bring.
The Factory should be an independent piece of code, used by client code to create instances. You have to decide somewhere in your program what concrete instance to create. Factory Method allows you to avoid having the same decision spread out through your client code. If later you want to change the implementation (or e.g. for testing), you have just one place to edit: this may be e.g. a simple global change, through conditional compilation (usually for tests), or even via a dependency injection configuration file.
Be careful about how client code communicates what kind of implementation it wants: that's not an uncommon way of reintroducing the dependencies factories are meant to hide.
It's not uncommon to see factory member functions in a class, but it makes my eyes bleed. Often their use have been mixed up with the functionality of the named constructor idiom. Moving the creation function(s) to a separate factory class will buy you more flexibility also to swap factories during testing.
When the interface is just for hiding the implementation details and there will be only one implementation of the Base interface ever, it could be ok to couple them. In that case, the factory function is just a new name for the constructor of the actual implementation.
However, that case is rare. Except when explicit designed having only one implementation ever, you are better off to assume that multiple implementations will exist at some point in time, if only for testing (as you discovered).
So usually it is better to split the Factory part into a separate class.
I have a code base where many of the classes I implement derive from classes that are provided by other divisions of my company. Working with these other devisions often have the working relationship as though they are third party middle ware vendors.
I'm trying to write test code without modifying these base classes. However, there are issues with creating meaningful test
objects due to the lack of interfaces:
//ACommonClass.h
#include "globalthermonuclearwar.h" //which contains deep #include dependencies...
#include "tictactoe.h" //...and need to exist at compile time to get into test...
class Something //which may or may not inherit from another class similar to this...
{
public:
virtual void fxn1(void); //which often calls into many other classes, similar to this
//...
int data1; //will be the only thing I can test against, but is often meaningless without fxn1 implemented
//...
};
I'd normally extract an interface and work from there, but as these are "Third Party", I can't commit these changes.
Currently, I've created a separate file that holds fake implementations for functions that are defined in the third-party supplied base class headers on a need to know basis, as has been described in the book "Working with Legacy Code".
My plan was to continue to use these definitions and provide alternative test implementations for each third party class that I needed:
//SomethingRequiredImplementations.cpp
#include "ACommonClass.h"
void CGlobalThermoNuclearWar::Simulate(void) {}; // fake this and all other required functions...
// fake implementations for otherwise undefined functions in globalthermonuclearwar.h's #include files...
void Something::fxn1(void) { data1 = blah(); } //test specific functionality.
But before I start doing that I was wondering if any one has tried providing actual objects on a code base similar to mine, which would allow creating new test specific classes to use in place of actual third-party classes.
Note all code bases in question are written in C++.
Mock objects are suitable for this kind of task. They allow you to simulate the existence of other components without needing them to be present. You simply define the expected input and output in your tests.
Google have a good mocking framework for C++.
I'm running into a very similar problem at the moment. I don't want to add a bunch of interfaces that are only there for the purpose of testing, so I can't use any of the existing mock object libraries. To get around this I do the same thing, creating a different file with fake implementations, and having my tests link the fake behaviour, and production code links the real behaviour.
What I wish I could do at this point, is take the internals of another mock framework, and use it inside my fake objects. It would look a little something like this:
Production.h
class ConcreteProductionClass { // regular everyday class
protected:
ConcreteProductionClass(); // I've found the 0 arg constructor useful
public:
void regularFunction(); // regular function that I want to mock
}
Mock.h
class MockProductionClass
: public ConcreteProductionClass
, public ClassThatLetsMeSetExpectations
{
friend class ConcreteProductionClass;
MockTypes membersNeededToSetExpectations;
public:
MockClass() : ConcreteProductionClass() {}
}
ConcreteProductionClass::regularFunction() {
membersNeededToSetExpectations.PassOrFailTheTest();
}
ProductionCode.cpp
void doSomething(ConcreteProductionClass c) {
c.regularFunction();
}
Test.cpp
TEST(myTest) {
MockProductionClass m;
m.SetExpectationsAndReturnValues();
doSomething(m);
ASSERT(m.verify());
}
The most painful part of all this is that the other mock frameworks are so close to this, but don't do it exactly, and the macros are so convoluted that it's not trivial to adapt them. I've begun looking into this on my spare time, but it's not moving along very quickly. Even if I got my method working the way I want, and had the expectation setting code in place, this method still has a couple drawbacks, one of them being that your build commands can get to be kind of long if you have to link against a lot of .o files rather than one .a, but that's manageable. It's also impossible to fall through to the default implementation, since we're not linking it. Anyway, I know this doesn't answer the question, or really even tell you anything you don't already know, but it shows how close the C++ community is to being able to mock classes that don't have a pure virtual interface.
You might want to consider mocking instead of faking as a potential solution. In some cases you may need to write wrapper classes that are mockable if the original classes aren't. I've done this with framework classes in C#/.Net, but not C++ so YMMV.
If I have a class that I need under test that derives from something I can't (or don't want to) run under test I'll:
Make a new logic-only class.
Move the code-i-wanna-test to the logic class.
Use an interface to talk back to the real class to interact with the base class and/or things I can't or won't put in the logic.
Define a test class using that same interface. This test class could have nothing but noops or fancy code that simulates the real classes.
If I have a class that I just need to use in testing, but using the real class is a problem (dependencies or unwanted behaviors):
I'll define a new interface that looks like all of the public methods I need to call.
I'll create a mock version of the object that supports that interface for testing.
I'll create another class that is constructed with a "real" version of that class. It also supports that interface. All interface calls a forwarded to the real object methods.
I'll only do this for methods I actually call - not ALL the public methods. I'll add to these classes as I write more tests.
For example, I wrap MFC's GDI classes like this to test Windows GDI drawing code. Templates can make some of this easier - but we often end up not doing that for various technical reasons (stuff with Windows DLL class exporting...).
I'm sure all this is in Feather's Working with Legacy Code book - and what I'm describing has actual terms. Just don't make me pull the book off the shelf...
One thing you did not indicate in your question is the reason why your classes derive from base classes from the other division. Is the relationship really a IS-A relationshiop ?
Unless your classes needs to be used by a framework, you could consider favoring delegation over inheritance. Then you can use dependency injection to provide your class with a mock of their class in the unit tests.
Otherwise, an idea would be to write a script to extract and create the interface your need from the header they provide, and integrate this to the compilation process so your unit test can ve checked in.