delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/12/31/10:35:45

Comments: Authenticated sender is <mert0407 AT sable DOT ox DOT ac DOT uk>
From: "George Foot" <george DOT foot AT merton DOT ox DOT ac DOT uk>
To: "Floris van den Berg" <remu AT multiweb DOT nl>
Date: Thu, 31 Dec 1998 15:34:59 +0000
MIME-Version: 1.0
Subject: Re: allegro timer pointed to object
CC: djgpp AT delorie DOT com
X-mailer: Pegasus Mail for Win32 (v2.42a)
Message-Id: <E0zvk8M-0002D0-00.1998-12-31-15-35-34@mail13.svr.pol.co.uk>
Reply-To: djgpp AT delorie DOT com

On 30 Dec 98 at 23:09, Floris van den Berg wrote:

> Anyone ever tried to let the timer of allegro point to a object method? I
> have a small snippet that compiles, but crashes when i start it.
...
> void Oallegro::breathe()
> {
>   install_int_ex(Oallegro::messagepump, MSEC_TO_TIMER(20));
> }
...
> Everything goes wrong when messagepump() is called. When i put a simple
> printf into the method, there's no problem at all. But when i do something
> with variables or call one of my other (virtual) classes, the program
> crashes.

Allegro's routine calls the method as if it were a normal 
function, but it is not -- it is a method.  Methods, when 
called, get an implicit parameter -- the object to which they 
are being applied.  When Allegro makes the call it won't be 
passing this parameter.  The reason your simple methods worked 
was that they never used the parameter; non-trivial methods 
will use that parameter and probably try to dereference a bad 
pointer.

Solutions to this problem are not simple.  I seem to remember 
writing a lot about it once to the Allegro mailing list; try 
looking in the list archives.  I think my possible solutions 
were three:

A) Make a static function which knows which object to pass to
the method, and install this as the handler.  Pro: simple.  
Con: Pretty much useless -- only one object can be registered 
in this way.

B) Make one of these functions for each object of the class, on 
initialisation.  The function is tailored specifically for the 
object to which it belongs.  You can write the simple 
function in C++, then examine the machine code output (use a 
debugger) to decide which bytes to set to the address of the 
object.  ALternatively, if you know the calling convention you 
can write the machine code yourself.  It would also be possible 
to make the program examine memory in a few sample copies of 
the function, and find the bytes to modify itself.  I prefer 
the second method I think.  Then you need to make the 
constructor for the object allocate some memory, copy in the 
code and update the bytes that need changing.  Pro: Effective 
and versatile.  Con: More complicated.

C) Rewrite Allegro's timer routines, making them also know how 
to call C++ methods.  Pro: Neat.  Con: More work; involves 
changing the library.

My favourite is B, I think.  I've never done any of these 
though.

-- 
george DOT foot AT merton DOT oxford DOT ac DOT uk

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019