COM Expertise needed: COM Callbacks

Mike B Johnson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Wed May 3 06:55:29 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;
> }
>
> AddRef/Release perform the COM object's reference counting, so 
> you should implement them too.
>


I wrapped the COM interface that is returned by PS and the 
queryInterface works and everything passes(as it should) but when 
I use your query interface it results in the COM error specified. 
Seems that the QueryInterface code is not 100% correct or 
something else is going on.

What I notices is that when PS's QueryInterface routine is used, 
it is called only 3 times(queries 3 interfaces like IUnknown, 
etc) while when I use your code about 10 interfaces are 
queried(including those 3 from PS).

PS's RGB QueryInterface

QueryInterface Called: 00000003-0000-0000-C00-000000000046(GUID), 
19F178(Object)
QueryInterface Called: 
ECC8691B-C1DB-4DC0-855E-65F6C551AF49(GUID), 19F124(Object)
QueryInterface Called: 00000003-0000-0000-C00-000000000046(GUID), 
19EFE8(Object)
main.icRGBColor.Release



Yours

QueryInterface Called: 00000003-0000-0000-C00-000000000046(GUID), 
19F178(Object)        Not Supported
QueryInterface Called: 
ECC8691B-C1DB-4DC0-855E-65F6C551AF49(GUID), 19F124(Object)       
Not Supported
QueryInterface Called: 00000003-0000-0000-C00-000000000046(GUID), 
19EFE8(Object)        Not Supported
QueryInterface Called: 0000001B-0000-0000-C00-000000000046(GUID), 
19F00C(Object)        Not Supported
QueryInterface Called: 00000000-0000-0000-C00-000000000046(GUID), 
19F040(Object)        IUnknown Supported
main.icRGBColor.AddRef
QueryInterface Called: 00000018-0000-0000-C00-000000000046(GUID), 
19EF1C(Object)        Not Supported
QueryInterface Called: 
334D391F-0E79-3B15-C9FF-EAC65DD07C42(GUID), 19EEF4(Object)       
Not Supported
QueryInterface Called: 00000040-0000-0000-C00-000000000046(GUID), 
19EF30(Object)        Not Supported
QueryInterface Called: 
334D391F-0E79-3B15-C9FF-EAC65DD07C42(GUID), 19EEF4(Object)       
Not Supported
QueryInterface Called: 
94EA2B94-E9CC-49E0-C0FF-EE64CA8F5B90(GUID), 19EF34(Object)       
Not Supported
QueryInterface Called: 
334D391F-0E79-3B15-C9FF-EAC65DD07C42(GUID), 19EEF4(Object)       
Not Supported
QueryInterface Called: 
77DD1250-139C-2BC3-BD95-900ACED61BE5(GUID), 19EF2C(Object)       
Not Supported
QueryInterface Called: 
334D391F-0E79-3B15-C9FF-EAC65DD07C42(GUID), 19EEF4(Object)       
Not Supported
QueryInterface Called: 
BFD60505-5A1F-4E41-88BA-A6FB07202DA9(GUID), 19EF28(Object)       
Not Supported
QueryInterface Called: 
334D391F-0E79-3B15-C9FF-EAC65DD07C42(GUID), 19EEF4(Object)       
Not Supported
QueryInterface Called: 
03FB5C57-D534-45F5-A1F4-D39556983875(GUID), 19EF24(Object)       
Not Supported
QueryInterface Called: 
334D391F-0E79-3B15-C9FF-EAC65DD07C42(GUID), 19EEF4(Object)       
Not Supported
QueryInterface Called: 
2C258AE7-50DC-49FF-9D1D-2ECB9A52CDD7(GUID), 19EF20(Object)       
Not Supported
QueryInterface Called: 00000019-0000-0000-C00-000000000046(GUID), 
2B5A3C0(Object)       Not Supported
QueryInterface Called: 
4C1E39E1-E3E3-4296-AA86-EC938D896E92(GUID), 19EF18(Object)       
Not Supported
main.icRGBColor.Release
QueryInterface Called: 00020400-0000-0000-C00-000000000046(GUID), 
19ED8C(Object)        IDispatch Supported
main.icRGBColor.AddRef
QueryInterface Called: 
F37B4894-3ED2-48AF-AD38-BB1B27E93869(GUID), 2D3EAAC(Object)      
Not Supported
QueryInterface Called: 00000003-0000-0000-C00-000000000046(GUID), 
19EFE8(Object)



I don't know if things are passed off to another query method or 
what. The query interface I use is


	// IUnknown
	int QueryInterface(const(GUID)* riid, void** pvObject)
	{
		write("QueryInterface Called: ", Guid2Str(*riid), "(GUID), ", 
pvObject, "(Object)");
		//version(wrap)
		{
			writeln();

			return rgb.iDispatch.QueryInterface(riid, pvObject);
		}

		// Always set out parameter to NULL, validating it first.
		if (pvObject is null) return E_POINTER;
		*pvObject = null;

		if (*riid == IID_IUnknown)
		{
			*pvObject = cast(void*)cast(IUnknown)this;
			writeln("\tIUnknown Supported");
		}
		else if (*riid == IID_IDispatch)
		{
			*pvObject = cast(void*)cast(IDispatch)this;
			writeln("\tIDispatch Supported");
		}

	
		// and so on for all interfaces we support
		
		if (*pvObject is null)
		{
			writeln("\tNot Supported");
			return E_NOINTERFACE;
		}

		//(cast(IUnknown)this).AddRef();
		return S_OK;

	}


Any ideas where to proceed?


More information about the Digitalmars-d-learn mailing list