Board index » cppbuilder » Can't call a method in my COM Object

Can't call a method in my COM Object

Hello,

    This is the nearest forum I can find to COM objects.  I am trying to
compile a COM object very closely related to Active X which has an imported
type library.  All compiles well until I introduce a statement within my
ProcessRequest (Web application) function to call Get_response(.....) within
the COM object whereupon I get the error message cannot find function
Get_Response().

   It may well be because all the method declarations within the type
library are abstract.  However, I don't know where to progress next - what
to read - or whatever.  Is this a common cry from users, that you're well
used to and can point out the error of my ways.  If so I would be extremely
grateful.

Sincerely

John Blackburn

 

Re:Can't call a method in my COM Object


I don't know where to look next;  your help would be greatly appreciated

Sincerely

John Blackburn

The following describes the problem in detail  :-

I am having difficulty accessing a method within a COM object;
specifically,
an automation object that is used to process requests from a web dispatcher.
I keep
getting the compiler error message "get_Response is not a memer of
IESDWebDataPtr".

Code is  :-

In my project TestProjIMPL unit :-
===============================

STDMETHODIMP TtestprojImpl::ProcessRequest(IESDWebDataPtr* WebData)
{
  try
  {
    IESDResponsePtr* Value;
    WebData->get_Response(Value).Content = "Hello World";

  /* The parameter list for this method may contain a smart pointer *
   * interface wrapper. This wrapper will automatically free the    *
   * underlying interface upon exit from the method. The pointer may*
   * need to have its reference count incremented in order for this *
   * to function properly when invoked from a client not written in *
   * C++Builder, if the client expects to free the interface.       */
  }
  catch(Exception &e)
  {
    return Error(e.Message.c_str(), IID_IESDConnect_ApplicationServer);
  }
  return S_OK;

Quote
};

Now, the declaration of IESDWebDataPtr is  :-

In the type library header :-
===========================

typedef TComInterface<IESDWebData, &IID_IESDWebData> IESDWebDataPtr;

Hence, this is defined on a COM interface and the operator -> is defined as
:-

  T* operator->() const
  {
    _ASSERTE_(intf != 0 /* Don't allow ->() of smart interface with NULL
pointer interface */);
    return intf;
  }

  T* operator->()
  {
    _ASSERTE_(intf != 0 /*Don't allow ->() of smart interface with NULL
pointer interface */);
    return intf;
  }

One is for a constant and the other for a variable;  however, in both cases
they return
an interface.  I don't know, therefore,  how to reference through to get at
the get_Response
method which exists in the type library EsdConnectserver_tlb which is marked
as used by the COM oject.

I'm sure that I'm going round the houses in a complicated way and someone
will point out
that it is straight forward an I've got it round my neck but, at the moment,
I can't see it.
It is, however, my first bash at COM objects.

Quote
"John Blackburn" <jo...@lintonhealy.demon.co.uk> wrote in message

news:8uue27$6s910@bornews.inprise.com...
Quote
> Hello,

>     This is the nearest forum I can find to COM objects.  I am trying to
> compile a COM object very closely related to Active X which has an
imported
> type library.  All compiles well until I introduce a statement within my
> ProcessRequest (Web application) function to call Get_response(.....)
within
> the COM object whereupon I get the error message cannot find function
> Get_Response().

>    It may well be because all the method declarations within the type
> library are abstract.  However, I don't know where to progress next - what
> to read - or whatever.  Is this a common cry from users, that you're well
> used to and can point out the error of my ways.  If so I would be
extremely
> grateful.

> Sincerely

> John Blackburn

Re:Can't call a method in my COM Object


does the IESDWebData interface have the method in question?

.a

Quote
John Blackburn wrote:
> [snip]

Re:Can't call a method in my COM Object


Yes,

Here is the relevant extract from ESDConnectserver_TLB.h;  also, note
that this type library works perfectly under Delphi and, of course this file
is auto generated form the type library.  Near the beggining for the extract
you will see the declaration of the get_Response method.

Sincerely

John

// *********************************************************************//
// Interface: IESDWebData
// Flags:     (4416) Dual OleAutomation Dispatchable
// GUID:      {40D18D4F-EACF-11D3-8E01-00104BB37768}
// *********************************************************************//
interface IESDWebData  : public IDispatch
{
public:
  virtual HRESULT STDMETHODCALLTYPE get_UserID(long* Value/*[out,retval]*/)
= 0; // [1]
  virtual HRESULT STDMETHODCALLTYPE set_UserID(long Value/*[in]*/) = 0; //
[1]
  virtual HRESULT STDMETHODCALLTYPE get_Command(BSTR* Value/*[out,retval]*/)
= 0; // [2]
  virtual HRESULT STDMETHODCALLTYPE set_Command(BSTR Value/*[in]*/) = 0; //
[2]
  virtual HRESULT STDMETHODCALLTYPE get_Script(BSTR* Value/*[out,retval]*/)
= 0; // [3]
  virtual HRESULT STDMETHODCALLTYPE set_Script(BSTR Value/*[in]*/) = 0; //
[3]
  virtual HRESULT STDMETHODCALLTYPE
get_Request(Esdconnectserver_tlb::IESDRequestPtr* Value/*[out,retval]*/) =
0; // [4]
  virtual HRESULT STDMETHODCALLTYPE
set_Request(Esdconnectserver_tlb::IESDRequestPtr Value/*[in]*/) = 0; // [4]
  virtual HRESULT STDMETHODCALLTYPE
get_Response(Esdconnectserver_tlb::IESDResponsePtr* Value/*[out,retval]*/) =
0; // [5]
  virtual HRESULT STDMETHODCALLTYPE
set_Response(Esdconnectserver_tlb::IESDResponsePtr Value/*[in]*/) = 0; //
[5]
  virtual HRESULT STDMETHODCALLTYPE
get_Literals(Esdconnectserver_tlb::IESDLiteralsPtr* Value/*[out,retval]*/) =
0; // [6]
  virtual HRESULT STDMETHODCALLTYPE
set_Literals(Esdconnectserver_tlb::IESDLiteralsPtr Value/*[in]*/) = 0; //
[6]
  virtual HRESULT STDMETHODCALLTYPE get_Content(BSTR* Value/*[out,retval]*/)
= 0; // [7]
  virtual HRESULT STDMETHODCALLTYPE set_Content(BSTR Value/*[in]*/) = 0; //
[7]

#if !defined(__TLB_NO_INTERFACE_WRAPPERS)

  long __fastcall get_UserID(void)
  {
    long Value;
    OLECHECK(this->get_UserID((long*)&Value));
    return Value;
  }

  BSTR __fastcall get_Command(void)
  {
    BSTR Value = 0;
    OLECHECK(this->get_Command((BSTR*)&Value));
    return Value;
  }

  BSTR __fastcall get_Script(void)
  {
    BSTR Value = 0;
    OLECHECK(this->get_Script((BSTR*)&Value));
    return Value;
  }

  Esdconnectserver_tlb::IESDRequestPtr __fastcall get_Request(void)
  {
    Esdconnectserver_tlb::IESDRequestPtr Value;

OLECHECK(this->get_Request((Esdconnectserver_tlb::IESDRequestPtr*)&Value));
    return Value;
  }

  Esdconnectserver_tlb::IESDResponsePtr __fastcall get_Response(void)
  {
    Esdconnectserver_tlb::IESDResponsePtr Value;

OLECHECK(this->get_Response((Esdconnectserver_tlb::IESDResponsePtr*)&Value))
;
    return Value;
  }

  Esdconnectserver_tlb::IESDLiteralsPtr __fastcall get_Literals(void)
  {
    Esdconnectserver_tlb::IESDLiteralsPtr Value;

OLECHECK(this->get_Literals((Esdconnectserver_tlb::IESDLiteralsPtr*)&Value))
;
    return Value;
  }

  BSTR __fastcall get_Content(void)
  {
    BSTR Value = 0;
    OLECHECK(this->get_Content((BSTR*)&Value));
    return Value;
  }

  __property   long            UserID = {read = get_UserID, write =
set_UserID};
  __property   BSTR            Command = {read = get_Command, write =
set_Command};
  __property   BSTR            Script = {read = get_Script, write =
set_Script};
  __property   Esdconnectserver_tlb::IESDRequestPtr Request = {read =
get_Request, write = set_Request};
  __property   Esdconnectserver_tlb::IESDResponsePtr Response = {read =
get_Response, write = set_Response};
  __property   Esdconnectserver_tlb::IESDLiteralsPtr Literals = {read =
get_Literals, write = set_Literals};
  __property   BSTR            Content = {read = get_Content, write =
set_Content};

#endif //   __TLB_NO_INTERFACE_WRAPPERS

Quote
};

"Alex Bakaev [TeamB]" <al...@jetsuite.com> wrote in message
news:3A1464C8.2250D965@jetsuite.com...
Quote
> does the IESDWebData interface have the method in question?

> .a

> John Blackburn wrote:
> > [snip]

Re:Can't call a method in my COM Object


John,

You are getting a IESDWebDataPtr* as a parameter, not a IESDWebData *,  Does
this wrapper class contain the function get_Response?

These wrapper classes that BCB 5 uses can be a real pain.

It looks to me you that get_Response returns an HRESULT, which does not have
a .Content attribute.
Are you sure you shouldn't be doing:

    IESDResponsePtr *Value;
    WebData->get_Response(Value);
    Value->Content = "Hello World";

Or

    IESDResponsePtr Value;
    WebData->get_Response(&Value);
    Value.Content = "Hello World";

Hope this helps.

Re:Can't call a method in my COM Object


Regrettably, the parser gives up before it gets to the .Content bit;  the
cursor stops at the
end of get_Response saying function does not exist.

John

Quote
"Steve Cox" <steve....@datria.com> wrote in message

news:8v3nur$i9e5@bornews.inprise.com...
Quote
> John,

> You are getting a IESDWebDataPtr* as a parameter, not a IESDWebData *,
Does
> this wrapper class contain the function get_Response?

> These wrapper classes that BCB 5 uses can be a real pain.

> It looks to me you that get_Response returns an HRESULT, which does not
have
> a .Content attribute.

> Are you sure you shouldn't be doing:

>     IESDResponsePtr *Value;
>     WebData->get_Response(Value);
>     Value->Content = "Hello World";

> Or

>     IESDResponsePtr Value;
>     WebData->get_Response(&Value);
>     Value.Content = "Hello World";

> Hope this helps.

Re:Can't call a method in my COM Object


To be accurate, (I misremembered the error message) it said get_Response is
not a member of IESDWebDataPtr.  What is interesting is that when I did the
following :-

WebData->get_Response(Value);
Value->Content = "Hello World"

I got two error messages :-

get_Response is not a member of IESDWebDataPtr
Content is not a member of IESDResponsePtr

What is going on here ?     Compiling to Delphi gets it right
Compiling to C++ Builder gets it wrong;  both systems are
auto generated with the exception of the two statements above.

This is a real brick wall - it shouldn't be this hard,  what is wrong ?

John

Quote
"John Blackburn" <jo...@lintonhealy.demon.co.uk> wrote in message

news:8v3r38$i9f5@bornews.inprise.com...
Quote
> Regrettably, the parser gives up before it gets to the .Content bit;  the
> cursor stops at the
> end of get_Response saying function does not exist.

> John

> "Steve Cox" <steve....@datria.com> wrote in message
> news:8v3nur$i9e5@bornews.inprise.com...
> > John,

> > You are getting a IESDWebDataPtr* as a parameter, not a IESDWebData *,
> Does
> > this wrapper class contain the function get_Response?

> > These wrapper classes that BCB 5 uses can be a real pain.

> > It looks to me you that get_Response returns an HRESULT, which does not
> have
> > a .Content attribute.

> > Are you sure you shouldn't be doing:

> >     IESDResponsePtr *Value;
> >     WebData->get_Response(Value);
> >     Value->Content = "Hello World";

> > Or

> >     IESDResponsePtr Value;
> >     WebData->get_Response(&Value);
> >     Value.Content = "Hello World";

> > Hope this helps.

Re:Can't call a method in my COM Object


John,

Have you tried:

(*WebData)->get_Response(Value);

I don't remember if the *Ptr functions use the -> or the . to get at
methods.

Re:Can't call a method in my COM Object


Thank you Steve,  I owe you a beer !

When I first looked at your suggestion, I thought;  I've done that already
and it didn't work.  However,  I thought, what the hell,  I tried it and it
worked.  Obviously it wasn't one of the many things I tried;  you can get a
bit punchy after a while.

As far as I can see,  the route of access is via IESDWebDataPtr which is
typedefed :-

typedef TComInterface<IESDWebData, .....> IESDWebDataPtr;

Via this template you get to IESDWebData and thence to get_Response() via
the operator-> overload in TComInterface which returns a pointer to an
interface (IESDWebData).

I suppose the good thing is that I learnt a lot about COM objects on the
way.

Many thanks again Steve and to Alex.

Quote
"Steve Cox" <steve....@datria.com> wrote in message

news:8v40o8$ic86@bornews.inprise.com...
Quote
> John,

> Have you tried:

> (*WebData)->get_Response(Value);

> I don't remember if the *Ptr functions use the -> or the . to get at
> methods.

Other Threads