Is it must to change COM interface UID when adding new functions - windows

I have a COM interface exposed from my application which is used by the third party plugins. Now, I need to add a new method to this interface but can not change the GUID of the interface as it will break all the existing plugins. I was told that if I add the new methods at the end of the interface it will work without issues as finally COM interface is a table of function pointers. These new methods will only be used by newly written plugins. I read this post and the first comment in Raymond Chen's blog: http://blogs.msdn.com/b/oldnewthing/archive/2005/11/01/487658.aspx but the situation mentioned in comment won't happen in my case as it is Windows only application. I know theoretically I should change the interface GUID. What would be the correct solution in this case? or will this approach work?

You can usually get away with adding new methods to the end of an existing interface without breaking compatibility. But as you have been reading, there are subtle cases where this can break. Especially when multiple inheritance is already being used.
The correct solution is to simply declare a new interface for the new methods. Leave your existing interfaces alone. Then have your existing objects implement both interfaces or use inheritance to have the new interface inherit from the old.
For example, if this is our original code. (I'll pretend this is done without IDL files for brevity).
Original code:
class IPublicInterface : public IUnknown
{
public:
virtual void M1() = 0;
virtual void M2() = 0;
}
class MyPublicClass : IPublicInterface
{
public:
// IPublicInterface
void M1();
void M2();
// IUnknown
HRESULT QueryInterface(...);
ULONG AddRef();
ULONG Release();
};
Now let's say we want to add a new method to this object called M3 without breaking users of the existing interface and object. The correct solution would be to add a new interface. For convenience, it can just inherit from the original interface.
class IPublicInterface2 : public IPublicInterface
{
public:
virtual void M3() = 0;
};
Now modify the class to inherit from both this new derived interface:
class MyPublicClass : public IPublicInterface2
{
public:
// IPublicInterface
void M1();
void M2();
// IPublicInterface2
void M3();
// IUnknown
HRESULT QueryInterface(...);
ULONG AddRef();
ULONG Release();
};
Update QueryInterface to support both calls for both the original UUID of IPublicInterface as well as IPublicInterface2.
HRESULT MyPublicClass::QueryInterface(GUID& iid, void** ppv)
{
// QI request for original interface
if ((iid == uuidof(IPublicInterface) || (iid == uuidof(IUnknown))
{
*ppv = (IPublicInterface*)this;
AddRef();
return S_OK;
}
else if (iid == uuidof(IPublicInterface2)
{
*ppv = (IPublicInterface2*)this;
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
Alternatively, IPublicInterface2 does not need to inherit from the original IPublicInterface. In that case, the implementing class inherits from both interfaces. In the QueryInterface implementation, you will need to be consistent about how you handle a possible ambiguous cast to IUnknown.

Related

c++11 access members of union content via pointer

working on implementing an Serial receive library for a specific hardware sending information to a ESP8266 device, I came across the following issue
for some background:
I use sloeber the eclipse IDE for arduino programming, with Arduino IDE the same issue exists
__cplusplus gives me 201103, so I assume I am on c++11
explanation of the setup:
I have derived classes which represents interpreted packages received from serial
these classes are all derived form on base class which implements some common methods, here methodA (in reality: length of
data, and getter for the data)
to forward these packets around I have created a class which has a member of a struct (sData) which has a tagged union inside. for simplicity I only use sData here not the class containing it.
the union uUnion is the one holding the packets content in form of derived packages, only one at a time, but able to contain every derived class available.
i do not use any dynamic object creation (no new), to prevent memory leaks
maybe there are better solution to this problem. Ideas are appreciated. But I would like to focus on why my implementation is not working
problem
the usage of the members-functions of the derived classes out of the union.
I can call them directly without problem.
But I am not able to create a pointer out of the union to the derived class instance and call that member.
//this is the base class
class cBaseA{
public:
virtual void methodA(void){
Serial.print(" A ");
Serial.println(i);
}
int i; //some attribute to work with
private:
};
//first derived class
class cDerivedA: public cBaseA{
public:
void methodA(void) {
Serial.print(" DerivedA ");
Serial.print(i);
Serial.print(" ");
Serial.println(ii);
}
int ii; //additional attribute
private:
};
//second derived class
class cDerivedB: public cBaseA{
public:
void methodA(void) {
Serial.print(" DerivedB ");
Serial.print(i);
Serial.print(" ");
Serial.println(ii);
}
int ii;
private:
};
//third derived class
class cDerivedC: public cBaseA{
public:
void methodA(void) {
Serial.print(" DerivedC");
Serial.print(i);
Serial.print(" ");
Serial.println(ii);
}
int ii;
private:
};
//this is the structure to pass different derived instances around
struct sData{
enum eDataType{
eunkown,
eDerivedA,
eDerivedB,
eDerivedC
} DataType;
union uUnion{
cDerivedA DerivedA;
cDerivedB DerivedB;
cDerivedC DerivedC;
~uUnion(){};
uUnion(){};
} ;
uUnion DataUnion;
sData(void){DataType=eDataType::eunkown;};
sData(const sData &Data){
this->DataType=Data.DataType;
switch(this->DataType){
case eDataType::eDerivedA:
this->DataUnion.DerivedA=Data.DataUnion.DerivedA;break;
case eDataType::eDerivedB:
this->DataUnion.DerivedB=Data.DataUnion.DerivedB;break;
case eDataType::eDerivedC:
this->DataUnion.DerivedC=Data.DataUnion.DerivedC;break;
case eDataType::eunkown:
break;
}
}
~sData(){};
};
void DataFunction(struct sData *Data){
Serial.println("A1:");
Data->DataUnion.DerivedB.methodA(); //works fine
cDerivedB *DerivedB;
DerivedB=&(Data->DataUnion.DerivedB); //this works
DerivedB->methodA(); //compiles, but execution exception, code 28
}
void setup(){
Serial.begin(9600);
delay(2000);
sData Data;
cDerivedB DerivedB1;
DerivedB1.i=1;
DerivedB1.ii=2;
Data.DataType=sData::eDataType::eDerivedB;
Data.DataUnion.DerivedB=DerivedB1;
DataFunction(&Data);
}
what I tried so far:
the absence of the virtual destructor of cBaseA has no influence (I tried already with it)
to make the union anonymous did not changed anything
to make a reference to the unions content results in the same error:
cDerivedB &DerivedB;
DerivedB=&(Data->DataUnion.DerivedB);
DerivedB.methodA();
I am able to make copy to out of the union to the base class, but this causes slicing, and the call ends in the base class, not as I need in the derived class
the question is: why does this exception happen, if the direct call is possible?
What is the right way to get a handle (pointer, reference) of the unions content and call the member? I know that there are discussions out there, that unions should only contain simple data types. Is this just a flaw of the compiler (c+11) letting me write this?
But still, direct access is possible. Why not via pointer?
many thanks in advance if somebody is able to put that cloud away I can not see through.

Gtest and gmock in below code snippet though error

How to achieve gtest or gmock for the private and protected member function. I am new to gtest and gmock. Below is the code for which i need to do gtest or gmock along with my attemp.
constexpr static char _session[]{"S_ID"};
typedef struct {
int session;
} Session;
typedef std::function<void(const Session &)> SessionCallback_t;
class Service : public ParentService {
public:
Service();
void registerCallback(const SessionCallback_t & callback);
protected:
virtual void notifyHandler(const Json::Value & data) override;
virtual void notifyState();
private:
Session mSession;
SessionCallback_t mCallback;
void jsonParse(const Json::Value & json_data);
};
My Attemp which doesn't compile
class TestService : public Service {
public:
TestService(): Service() {
}
bool registerCallback(const SessionCallback_t & cb) {
// how to achive this?
}
};
class MyTestService : public ::testing::Test {
protected:
virtual void SetUp() {
}
virtual void TearDown() {
}
};
TEST_F(MyTestService , registerCallbackTest) {
TestService service;
EXPECT_TRUE(service.registerCallback(SessionCallback_t));
}
I am stuck with the below interface
1.registerCallback()
2.notifyHandler()
3.notifyState()
4.jsonParse()
Please though some light to proceed further.
Welcome to Stack Overflow!
First, let me recommend this recent episode of CppCast on Designing for Testing. The podcast notes that if you find your code is hard to test, it means it is too tightly coupled and is thus poorly designed.
It also (rightly, IMHO) recommends that you test only public functions. If you find yourself needing to test the private functions, you should probably refactor the code.
One way to do that is to break your code into multiple classes with the public functions you want to test. Then, your composite class can either create and own the class directly (appropriate if it's a basic type with no dependencies or complex resources of its own such as a vector or string class) or can use dependency injection to pass in the dependencies as constructor or method parameters (appropriate for databases, network connections, file systems, etc.).
Then in testing, you pass in a test double, such as a mocked object or a simplified implementation like an in-memory database instead of an out-of-process database connection, that acts like the object but does what you need in the test situation.
That's the basic advice. In your specific case, it looks like you're trying to override a non-virtual function in your TestService. What are you wanting to test exactly?
I wouldn't expect EXPECT_TRUE(service.registerCallback(SessionCallback_t)); to compile because SessionCallback_t names a type, not an instance of a type, so you can't pass it in. Again, what are you trying to accomplish?
Update to comment:
Mocking requires virtual functions (or duck typing) and dependency injection.
If you just want to test registerCallback(), I suspect you don't need a mock at all. Rather, you need to look at the function's documentation to see what it says it will do -- sometimes called the contract. For instance, what are the preconditions and postconditions of the function? What are the error cases it might encounter? These are what a unit test should cover.
For instance, does it retain only one callback (hint: as written, yes)? What happens when you call it when there is already a callback registered? Does it tolerate default-initialized std::function objects being passed in?
The bigger question is, how do you validate that your test is correct. If you start triggering notifications on your callback, you're venturing beyond the scope of testing this function in isolation. Instead, you could create an accessor class in your test to publicize what is private so you can validate. Still, you can't compare std::function for equality, so the best you can do is to invoke it and check that an expected side effect happens:
class TestService : public Service {
public:
const SessionCallback_t& getCallback() const { return mCallback; }
};
struct TestCallback
{
int mCount = 0;
void operator()( const Session& ) { ++mCount; }
};
Then in your test, you can write a tests like:
TEST_F(MyTestService , Test_registerCallback_BadCallback) {
auto service = TestService{};
EXPECT_THROW( service.registerCallback( SessionCallback_t{} ), std::out_of_range );
}
// Register and check that it's our callback
TEST_F(MyTestService , Test_registerCallback_CallbackSaved) {
auto service = TestService{};
auto callback = TestCallback{};
EXPECT_TRUE( service.registerCallback( callback ) );
EXPECT_EQ( callback.mCount, 0 );
auto actualCallback = service.getCallback();
EXPECT_TRUE( actualCallback );
actualCallback();
EXPECT_EQ( callback.mCount, 1 );
}
TEST_F(MyTestService , Test_registerCallback_CallbackOverwrite) {
auto service = TestService{};
auto callback1 = TestCallback{};
auto callback2 = TestCallback{};
EXPECT_TRUE( service.registerCallback( callback1 ) );
EXPECT_TRUE( service.registerCallback( callback2 ) );
EXPECT_EQ( callback1.mCount, 0 );
EXPECT_EQ( callback2.mCount, 0 );
auto actualCallback = service.getCallback();
EXPECT_TRUE( actualCallback );
actualCallback();
EXPECT_EQ( callback1.mCount, 0 );
EXPECT_EQ( callback2.mCount, 1 );
}

ABI-compatible shared_ptr implementation

I am working on a COM-style complier cross-compatible plugin framework relying on compatible virtual table implementations for ABI compatibility.
I define interfaces containing only pure virtual member functions and an overridden delete operator to channel destruction to the place of implementation.
This works well with extern "C" factory functions instantiating the plugin implementation of the interface and returning an interface-type pointer.
However, I was wondering if smart pointers wouldn't be a more modern way to manage the lifetime of the plugin object. I think I have actually managed to
create a standard-layout shared_ptr/weak_ptr that uses a reference count object defined and implemented the same way as the plugin interfaces.
It looks something like this:
class IRefCount
{
public:
virtual void incRef() = 0;
virtual void decRef() = 0;
virtual bool incRefIfNZ() = 0;
virtual void incWRef() = 0;
virtual void decWRef() = 0;
virtual long uses() const = 0;
protected:
~ref_count_base() = default; //prohibit automatic storage
}
template <typename Ty>
class shared_ptr
{
private:
Ty* ptr_;
IRefCount* ref_count_;
public:
//member functions as defined by C++11 spec
}
Three questions:
Before the smart pointer the factory function looked like this:
extern "C" IPlugin* factory() { try { return new Plugin(); } catch (...) { return nullptr; } }
Now, it looks like this:
extern "C" shared_ptr<IPlugin> factory() { try { return shared_ptr<IPlugin>(new Plugin()); } catch (...) { return nullptr; } }
VS2013 is giving me warning C4190: 'factory' has C-linkage specified, but returns UDT 'shared_ptr' which is incompatible with C. According to MSDN this is OK, provided that both caller and callee are C++.
Are there any other potential issues with returning standard-layout objects from "C" linkage functions?
Calling conventions. Should I be specifying __stdcall for all pure-virtual interface functions and factory functions?
I am using <atomic> for the reference count. I am writing platform-independent code and I have not yet tried compiling for ARM. According to http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/ch01s02s01.html armcc does not implement std::atomic. Any better compilers/stl out there?

A delegate to a virtual method where does it point to (base/derived)?

I recently started using C++/Cli for wrapping purposes.
Now I'm at a point where I've to know more about the internals.
Consider the following code:
Header file (ignoring .NET namespaces for this example):
public ref class BaseyClass
{
protected:
delegate void TestMethodDelegate(); // TestMethod delegate
BaseyClass(); // constructor
virtual void TestMethod(); // member: method
GCHandle _testMethodHandle; // member: method handle
};
CPP file (ignoring .NET namespaces for this example):
BaseyClass::BaseyClass()
{
_testMethodHandle
= GCHandle::Alloc(
gcnew TestMethodDelegate(this, &BaseyClass::TestMethod));
}
void TestMethod()
{
}
Eventually this class will be used as base class (for a DerivedClass) later and the method "TestMethod()" gets overridden and called from unmanaged code through the delegate pointer.
Now the question: Which method will be referenced by the delegate?
BaseyClass::TestMethod();
or
DerivedClass::TestMethod();
Personally I think the "BaseyClass::TestMethod()" will be referenced by the delegate because even when it's overridden, the delegate points to the (base-)address of BaseyClass. Hence a DerivedClass cannot override the "TestMethod" and use the delegate from BaseyClass.
I just want to be sure. Thanks for your comments and enlightment.
The delegate will be a reference to the derived class's TestMethod. Even though you're passing &BaseyClass::TestMethod, that's a virtual method, you're also passing this, which is the derived type, and both of those are taken into account when the delegate is created.
Other notes:
TestMethodDelegate doesn't need to be inside the class definition. The more standard way is to have the delegate outside of the class, just in the namespace. (Or use the existing built-in one, Action.)
You don't need to GCHandle::Alloc (I assume that's what you meant by Allow). Instead, declare _testMethodHandle as TestMethodDelegate^ (or Action^). In general, you shouldn't need to deal with GCHandle unless you're interfacing with unmanaged code, and this code is all managed.
Here's my test code:
public ref class BaseyClass
{
public:
BaseyClass() { this->_testMethodHandle = gcnew Action(this, &BaseyClass::TestMethod); }
virtual void TestMethod() { Debug::WriteLine("BaseyClass::TestMethod"); }
Action^ _testMethodHandle;
};
public ref class DerivedClass : BaseyClass
{
public:
virtual void TestMethod() override { Debug::WriteLine("DerivedClass::TestMethod"); }
};
int main(array<System::String ^> ^args)
{
BaseyClass^ base = gcnew DerivedClass();
base->_testMethodHandle();
return 0;
}
Output:
DerivedClass::TestMethod

How does COM select how to marshal an interface?

As I get it there're three ways to implement marshalling in COM:
typelib marshalling
proxy/stub marshalling
implementing IMarshal by the object
now how does the component consumer (user) choose which one will be used? Does it decide on its own and use the preferred way or does it call some built-in function and it solves the problem for it?
I currently experience the following: my component implements a custom interface ICustomInterface that is also implemented by a component from another company. My component doesn't have a typelib and doesn't implement IMarshal. The system registry contains the HKCR\Interface{uuidof(ICustomInterface)}\ProxyStubClsid32 key with a GUID of the proxy/stub that can be traced to a library provided by that other company.
Now when my component consumer initializes my component it calls QueryInterface() requesting IMarshal from my component and when returned E_NOINTERFACE it just does nothing. Why is this - why doesn't proxy/stub library from the other company kick in?
The COM runtime will use typelib (oleautomation) marshalling if you mark your interface as using the standard marshaler by adding its CLSID {00020424-0000-0000-C000-000000000046} under HKCR\Interfaces\{iid}\ProxyStubClsid (where {iid} is the GUID of your interface). You'll need to have a typelibrary registered too, in order for the runtime to extract the parameter information, and you can only use a certain subset of types. There's some more (old) information here and here.
If you want to use a custom proxy/stub, as generated by the MIDL compiler from your IDL, then you'll need to change the interface registry entry to be the CLSID of that proxy object instead. This enables you to use a wider range of types, e.g. "raw" arrays.
If you support IMarshal then that's what'll be used in preference to either of these mechanisms. This means you can change your object to aggregate the free-threaded marshaler (using its implementation of IMarshal) without having to change anything in the registry. This will avoid any proxies being created.
Hope this helps.
I am a bit rusty at this, but do you have a function named blindquery in your project ? (its usually declared by the wizard if you created a C++ ATL project). Breakpoint inside the function. The function is generated by the wizard often has problems with queryinterface returning E_NOINTERFACE due to buggy code.
edit (found sample code) from my old project _blindquery
class ATL_NO_VTABLE CChildEvents :
public CComObjectRootEx <CComSingleThreadModel>,
public CComCoClass<CChildEvents, &CLSID_ChildEvents>,
public IDispatchImpl<IChildEvents, &IID_IChildEvents, &LIBID_XXX>
{
public:
CChildEvents(void) :
m_pItfMgr(0)
{
}
/* called from internalQI to tear off a new blind interface */
static HRESULT WINAPI _BlindQuery(void *pvThis, REFIID riid, void **ppv, DWORD dw);
DECLARE_REGISTRY_RESOURCEID(IDR_CHILDEVENTS)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CChildEvents)
COM_INTERFACE_ENTRY(IChildEvents)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY_FUNC_BLIND(0, _BlindQuery)
END_COM_MAP()
};
HRESULT WINAPI CChildEvents::_BlindQuery(void *pvThis, REFIID riid, void **ppv, DWORD /* dw */ )
{
HRESULT hr = E_NOINTERFACE;
USES_CONVERSION;
try
{
if(pvThis == NULL)
{
ATLASSERT(FALSE);
}
else
{
/*
* cast the pvThis pointer to the actual class £
* so we can use it here £
* reinterpret_cast should be safe since we're calling ourself
*/
CChildEvents *pThis = reinterpret_cast < CChildEvents * > (pvThis);
if(pThis == NULL)
{
ATLASSERT(FALSE);
}
else
{
/* check to see if it matches on of our children's DIID */
if(memcmp(&riid,&l_someotherguid,sizeof(GUID)) == 0) {
/* if so cast to a IDispatch -- the standard for event interfaces */
*ppv = reinterpret_cast < IDispatch * > (pvThis);
/* addref */
pThis->AddRef();
/* reply */
hr = S_OK;
}
}
}
}
catch(...)
{
ATLASSERT(FALSE);
}
/* must not be in our map - tell them to GO FISH */
return(hr);
}

Resources