Subject: Re: EGCS-1.0.2-Mingw32
From: [email-masked] (Benjamin Riefenstahl)

12 Sep 1998 14:33:54 -0700
Message-ID: <[email-masked]>
References: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
To: [email-masked]

Hi Paul,

Paul Garceau wrote:
>         Yes.  egcs-1.0.2-mingw32 is attempting to map to a C++ class member
> (IDirectDraw::SetCooperativeLevel(int,dword)) defined within the actual 3d
> Renderer source code to something that it can understand and reference via
> the ddraw.h header file.  The ddraw.h file has no C++ classes references in it.

Hm, I don't understand. It looks like those DirectDraw classes are
regular COM objects, right?

The problems with COM and gcc as I understand it are these: g++ does not
currently support C++-style COM. COM objects are defined by a specific
vtable layout and g++ does not generate a compatible vtable.

OTOH all of the COM machinery is completely dynamic. I.e. there are no
name resolution issues at all, because methods are not actually called
by name but through the vtable instead. The vtable is nothing else but a
table of function pointers. So the vtable layout can be re-declared as a
C structure. There are code generators for this C-style access to COM
objects, but one can also write the code manually. For a generic
IUnknown it would be somewhat like:

  /*
   * Some general preparations.
   */
  typedef unsigned long HRESULT;
  #define COM_STDCALL __stdcall
  struct GUIID;
  /*
   * Declare the types of the individual methods.
   *
   * Do this in a separate step, because the placment of the
   * __stdcall modifier in function pointer declarations is
   * non-portable across compilers. In a direct function
   * declaration/typedef this is rather unambiguous though.
   */
  struct IUnknown; /*forward declaration*/
  typedef HESULT COM_STDCALL IUnknown_QueryInterface_t(
	struct IUnknown * obj,
	struct GUID * newiface_id
	void ** newiface_result
	);
  typedef unsigned long COM_STDCALL IUnknown_AddRef_t(
	struct IUnknown * obj
	);
  typedef unsigned long COM_STDCALL IUnknown_Release_t(
	struct IUnknown * obj
	);
  /*
   * The function pointer interface.
   */
  struct IUnknown_vtable
  {
	IUnknown_QueryInterface_t * QueryInterface;
        IUnknown_AddRef_t * AddRef;
        IUnknown_Release_t * Release;
  };
  /*
   * The object itself.
   */
  struct IUnknown
  {
	struct IUnknown_vtable * lpVtbl;
	/* the rest is private */
  };

The important points in this code are the structs IUnknown and
IUnknown_vtable. The rest just completes the picture.

If you have a pointer to an IUnknown object you use it like this

  struct IUnknown * iface = some_function();

  /* usually some_function() will have done the next step already */
  /*iface->lpVtbl->AddRef(iface);*/

  ... use iface ....

  iface->lpVtbl->Release(iface);

Paul Garceau wrote:
> code snippet:
> ...
> static LPDIRECTDRAW lpDD;
> ...
> ddrval = lpDD->SetCooperativeLevel (NULL, DDSCL_NORMAL);

Provided you have declared an IDirectDraw interface similar to the
IUnknown interface above, this is transformed to

  static struct IDirectDraw * lpDD;
  ...
  ddrval = lpDD->lpVtbl->SetCooperativeLevel( lpDD, NULL, DDSCL_NORMAL
);

so long, benny
======================================
Benjamin Riefenstahl ([email-masked])
Crocodial Communications EntwicklungsGmbH
Ruhrstraße 61, D-22761 Hamburg, Germany
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".