COM Expertise needed: COM Callbacks

Nierjerson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Apr 28 15:27:23 PDT 2017


On Friday, 28 April 2017 at 09:25:31 UTC, John Chapman wrote:
> On Thursday, 27 April 2017 at 20:20:23 UTC, Nierjerson wrote:
>>
>> I think the main issue though, is that I really don't know 
>> what is going on when I invoke the PS function. It seems to 
>> call the server method that takes the interface and then the 
>> server does it's "magic"(which is calling my QueryInterface) 
>> but how the implemented QueryInterface is suppose to respond 
>> is beyond me... I've tried some based stuff but nothing seem 
>> to work. The good news is that it is doing something(calling 
>> QueryInterface) which means that the server is at work.
>>
>> Any more ideas?  I think the issue currently is is the 
>> QueryInterface(it is simply not doing what it is suppose to). 
>> I'll probably have to look at some other implementations to 
>> see what is going on.
>
> QueryInterface is COM's version of opCast. It asks if you 
> support the interface represented by an IID (riid). If you 
> don't, then you return E_NOINTERFACE. If you do, then you point 
> the result (pvObject) to yourself and return S_OK. Here's a 
> basic implementation:
>
> extern(Windows)
> HRESULT QueryInterface(IID* riid, void** pvObject) {
>   if (pvObject is null) return E_POINTER;
>   *pvObject = null;
>
>   if (*riid == IID_IUnknown) *pvObject = 
> cast(void*)cast(IUnknown)this;
>   else if (*riid == IID_IDispatch) *pvObject = 
> cast(void*)cast(IDispatch)this;
>   // and so on for all interfaces we support
>
>   if (*pvObject is null) return E_NOINTERFACE;
>   (cast(IUnknown)this).AddRef();
>   return S_OK;
> }
>

Ok, I tried this and returned this but it didn't work. I didn't 
clal AddRef though, but maybe I was in the right direction but 
had some other issue.

> AddRef/Release perform the COM object's reference counting, so 
> you should implement them too.
>
> However, I don't understand why your icRBCColor class both 
> implements and encapsulates IDispatch - the generated version 
> cRGBColor from Gen.d just encapsulates it. Why do you need to 
> instantiate an instance of icRGBColor? Can't you just use the 
> rgb1 object you got from the dd.RGB() getter, assign the colour 
> values to its Red, Blue, Green properties as needed, then call 
> the dd.RGB(rgb1) setter? Does that not work?


cRGBColor and any class in Gen.d are not COM interfaces and can't 
be used. All they do is wrap the dynamic method invocation work 
that is required to interact with PS.

It may work that I could use them to set the values and then 
reset the instance but I feel that seems to be a waste. There is 
no need to really set the object if one is using the property 
setters. Although my method of creating a "direct" COM interface 
wrapper(one that inherits from IDispatch and simply delegates the 
work to the original com) seems to do basically the same, I plan 
on converting those COM Properties in to D properties and 
maintain state on both ends that are always in sync(possibly a 
bit slow, but should be easy to implement and allow one to work 
with COM in a more D like fashion.

I could, for example, just have those "c" classes inherit from 
IDispatch directly and then pass on the IDispatch COM calls to 
the underlying COM interface(which is stored in the c class). 
That would be a sort of combination of the two methods above and 
might be better as it avoids actually having to get any of the 
callback COM stuff working(the stuff I'm having a problem with 
now). I just wasn't sure if this method would work and didn't 
want to mess with the gen code too much before I had a better 
understanding of what is going on.

Regardless, getting the above code to work is still important as 
it will explain to me how it should work so that I understand for 
future purposes if this method does not go that route.

Thanks, I'll try to get it to work a again and report back.



More information about the Digitalmars-d-learn mailing list