15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Unable to call AddRef() on IDispatch *

BLR CSG -- SAMAL_C1@blrv1.verifone.com
Thursday, January 02, 1997

Environment : VC++ 4.2-flat, Windows NT 3.51

Hi,
 I have an OLE Local Server say Y.exe (written in VB), that serves an 
Object say X. My client app is in VC++
I've created a wrapper class for this object using class wizard, say Cx.

Now i create an instance using
Cx m_x ;
m_x.CreateInstance("Y.X") ;

I'm able to call Interface fn. implemented by the VB program but if i call 
m_x.AddRef() then i get a DISP_E_MEMBERNOTFOUND exception.

Also if i have a Interface fn. that returns another Object say GetObj(), 
then I'm able to call GetObj() itself but an AddRef on the returned 
LPINTERFACE fails. Some other fn. calls on this returned LPDISPATCH fails 
with DISP_E_BADPARAMCOUNT.

Can anybody please help me out with what i'm doing wrong or not doing.
Thanks in advance
Samal Chandran.
ps. I'm very much an OLE novice.



hemantab@hclt.com
Tuesday, January 07, 1997

Hi ,

> I have an OLE Local Server say Y.exe (written in VB), that serves an
>Object say X. My client app is in VC++
>I've created a wrapper class for this object using class wizard, say
>Cx.
>
>Now i create an instance using
>Cx m_x ;
>m_x.CreateInstance("Y.X") ;

I am  not sure whether i have been able to understand the above 
properly, if not then pl clarify...anyway

If ur are using VC++ to create the wrapper class then i suppose u are
talking of IClassFactory::CreateInstance..... In that case the call to
CreateInstance should be preceded by a call to CoGetClassObject() to
get the IClassFactory interface. Then u can call
IClassFactory::CreateInstance with appropriate parameters. The
parameters also seem to be incorrect.

>I'm able to call Interface fn. implemented by the VB program 

if u are planning to call other interface fns. from an EXE server then
i suppose u have the proxy and stub for marshalling in place.

> but if i call m_x.AddRef() then i get a DISP_E_MEMBERNOTFOUND
> exception.

AddRef should not doesn't throw any exceptions, coz normally AddRef()
implementation does not do any major stuff to throw exceptions. Maybe
ur m_x itself is not instantiated properly.

>Also if i have a Interface fn. that returns another Object say
>GetObj(), then I'm able to call GetObj() itself but an AddRef on the
>returned LPINTERFACE fails. 

The function GetObj() should do the AddRef() before giving u the
interface pointer. Anyway as a general rule only when copying pointers
explicit AddRef() is needed, as otherwise all functions which return
an interface pointer must do a AddRef() before giving the pointer.

>Some other fn. calls on this returned
>LPDISPATCH fails with DISP_E_BADPARAMCOUNT.

I don;t think whatever i have written will be of much use, it will be
easier if u can give the sources to know what exacly ur doing, u can
attach all the sources to the mail and directly mail me at
hemantab@hclt.com.

Hemanta 
___________________________________________________
Thought for the day:
Everyone should get married at sometime
Afterall happiness is not the only thing in life.


___________________________________________________
Thought for the day:
    Concerto (n): a fight between a piano and a pianist.




BLR CSG -- SAMAL_C1@blrv1.verifone.com
Wednesday, January 08, 1997

Hi,


>> I have an OLE Local Server say Y.exe (written in VB), that serves an
>>Object say X. My client app is in VC++
>>I've created a wrapper class for this object using class wizard, say
>>Cx.
>>
>>Now i create an instance using
>>Cx m_x ;
>>m_x.CreateInstance("Y.X") ;

>I am  not sure whether i have been able to understand the above 
>properly, if not then pl clarify...anyway

>If ur are using VC++ to create the wrapper class then i suppose u are
>talking of IClassFactory::CreateInstance..... In that case the call to
>CreateInstance should be preceded by a call to CoGetClassObject() to
>get the IClassFactory interface. Then u can call
>IClassFactory::CreateInstance with appropriate parameters. The
>parameters also seem to be incorrect.

Yep u have misunderstood the environment - My OLE server is written in VB, 
and the client I am writing in VC using MFC. So the wrapper i talk about is 
the COleDispatchDriver derived one that automatically gets generated by 
ClassWizard when i create a new class from OLE tlb/Exe/Dll. So the 
CreateInstance is a member fn. of COleDispatchDriver and so the parameters 
are right. I am getting an Interface * back.

>>I'm able to call Interface fn. implemented by the VB program 

>if u are planning to call other interface fns. from an EXE server then
>i suppose u have the proxy and stub for marshalling in place.

The dispatch * returned is from the VB server and so should be an IDispatch 
*, so VB should handle whatever marshalling is req. and also call the 
required AddRef().

>> but if i call m_x.AddRef() then i get a DISP_E_MEMBERNOTFOUND
>> exception.

>AddRef should not doesn't throw any exceptions, coz normally AddRef()
>implementation does not do any major stuff to throw exceptions. Maybe
>ur m_x itself is not instantiated properly.
I know, that's why i feel that the IDispatch * i get is behaving funny. 
Some Invokes work where as others don't.. I hope this clarifies my problem

------Rest of original post 'n reply ----------------

>Also if i have a Interface fn. that returns another Object say
>GetObj(), then I'm able to call GetObj() itself but an AddRef on the
>returned LPINTERFACE fails. 

The function GetObj() should do the AddRef() before giving u the
interface pointer. Anyway as a general rule only when copying pointers
explicit AddRef() is needed, as otherwise all functions which return
an interface pointer must do a AddRef() before giving the pointer.

>Some other fn. calls on this returned
>LPDISPATCH fails with DISP_E_BADPARAMCOUNT.

I don;t think whatever i have written will be of much use, it will be
easier if u can give the sources to know what exacly ur doing, u can
attach all the sources to the mail and directly mail me at
hemantab@hclt.com.

Hemanta 



Janakiraman M -- mjanaki@informix.com
Wednesday, January 08, 1997

At 09:07 AM 1/7/97 +0000, hemantab@hclt.com wrote:
>Hi ,
>
>> I have an OLE Local Server say Y.exe (written in VB), that serves an
>>Object say X. My client app is in VC++
>>I've created a wrapper class for this object using class wizard, say
>>Cx.
>>
>>Now i create an instance using
>>Cx m_x ;
>>m_x.CreateInstance("Y.X") ;
>
>I am  not sure whether i have been able to understand the above 
>properly, if not then pl clarify...anyway
>
>If ur are using VC++ to create the wrapper class then i suppose u are
>talking of IClassFactory::CreateInstance..... In that case the call to
>CreateInstance should be preceded by a call to CoGetClassObject() to
>get the IClassFactory interface. Then u can call
>IClassFactory::CreateInstance with appropriate parameters. The
>parameters also seem to be incorrect.
>

VC++ creates a Wrapper class which is derived from COleDispatchDriver. You
have to call its CreateDispatch Method with the Prog Id. first or
AttachDispatch if you already have a Dispatch.

>>I'm able to call Interface fn. implemented by the VB program 
>
>if u are planning to call other interface fns. from an EXE server then
>i suppose u have the proxy and stub for marshalling in place.
>
>> but if i call m_x.AddRef() then i get a DISP_E_MEMBERNOTFOUND
>> exception.
>
This is the expected behaviour. The Class Cx does not expose a method called
AddRef() through OLE Automation and so you cannot call it. The wrapper class
Cx generated does not correspond to the IDispatch exposed by your server.
The actual IDispatch is stored as a member variable of COleDispatchDriver -
m_lpDispatch. 
If you want to call AddRef, you should call it on m_x.m_lpDispatch->AddRef()
and not m_x.AddRef()

>AddRef should not doesn't throw any exceptions, coz normally AddRef()
>implementation does not do any major stuff to throw exceptions. Maybe
>ur m_x itself is not instantiated properly.
>
>>Also if i have a Interface fn. that returns another Object say
>>GetObj(), then I'm able to call GetObj() itself but an AddRef on the
>>returned LPINTERFACE fails. 
>
This is probably because of the same reason.

>The function GetObj() should do the AddRef() before giving u the
>interface pointer. Anyway as a general rule only when copying pointers
>explicit AddRef() is needed, as otherwise all functions which return
>an interface pointer must do a AddRef() before giving the pointer.
>
>>Some other fn. calls on this returned
>>LPDISPATCH fails with DISP_E_BADPARAMCOUNT.
>
>I don;t think whatever i have written will be of much use, it will be
>easier if u can give the sources to know what exacly ur doing, u can
>attach all the sources to the mail and directly mail me at
>hemantab@hclt.com.
>
>Hemanta 
>___________________________________________________
>Thought for the day:
>Everyone should get married at sometime
>Afterall happiness is not the only thing in life.
>
>
>___________________________________________________
>Thought for the day:
>    Concerto (n): a fight between a piano and a pianist.
>
>
>




hemantab@hclt.com
Tuesday, December 10, 1996

Hi, 

>Yep u have misunderstood the environment - My OLE server is written
>in VB, and the client I am writing in VC using MFC. So the wrapper i
>talk about is the COleDispatchDriver derived one that automatically
>gets generated by ClassWizard when i create a new class from OLE
>tlb/Exe/Dll. So the CreateInstance is a member fn. of
>COleDispatchDriver and so the parameters are right. I am getting an
>Interface * back.

Its not CreateInstance, its CreateDispatch in case u want to load the 
object and get an instance pointer , or use AttachDispatch if u 
already have a dispatch pointer...
CreateInstance is a member of IClassFactory interface, so i am not 
confused, the confusion is at ur end.

>The dispatch * returned is from the VB server and so should be an
>IDispatch *, so VB should handle whatever marshalling is req. and
>also call the required AddRef().

Yeah actually if ur using only standard interfaces like IUnknown , 
IDispatch etc. etc. etc. the marshalling is already there in 
compobj.dll. But in case of custom interfaces u have to use MIDL to 
generate the proxy and stub.In ur case i think ur talking of 
IDispatch only so things should be definitely fine. 

>I know, that's why i feel that the IDispatch * i get is behaving
>funny. Some Invokes work where as others don't.. I hope this
>clarifies my problem
i can only think of one case where this can happen, ur telling that 
ur Invoke fails saying some DISP_E_MEMBERNOTFOUND, that exception is 
normally thrown by IDispatch::GetIDsOfNames(). The implementation of 
GetIDsOfNames() normally has an array of function names and when the 
function name if passed to the function it returns a dispid which is 
used in a switch in Invoke() to invoke a method. 
So if it returns a exception DISP_E_MEMBERNOTFOUND that means (as far 
as my knowledge goes) ur implementation of GetIDsOfNames() is where 
the problem lies. 
I don't know what is done in VB , but in VC the GetIDsOfNames() is 
embedded as a macro DECLARE_DISPATCH_MAP .......
A small doubt maybe ur sending name as a char and ur VB server 
expects UNICODE....that's a small problem but can be a major pain (i 
have faced it). 


It will be easier if u can send me the code both client as well as 
server.

Bye 
Hemanta
___________________________________________________
Thought for the day:
Make a software idiot proof and someone will make a better idiot.





| Вернуться в корень Архива |