🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.c++
6 messages
6 total messages Started by Christian Horn Thu, 24 Aug 1995 17:03
Q: Adresse einer Methode
#307
Author: Christian Horn
Date: Thu, 24 Aug 1995 17:03
23 lines
922 bytes
Hi,

Es ist folgende Klasse gegeben:

class A
{
   public:
     void f1(void) {...}
     void f2(void) {...}
}

Nun soll die Methode f1 die Adresse von f2 nehmen und sie mittels
FP_SEG und FP_OFF in Segment und Offset zerlegen.

Das Problem ist, dass ich zwar die Adresse von f2 erhalte
(&A::f2), diese aber nicht nach void far* casten kann, um sie dann
FP_SEG bzw. FP_OFF als Argument uebergeben zu koennen.

Weiss jemand wie ich von der Methode f2 die Adresse erhalten kann, so
dass ich sie zerlegen kann?

Danke,
Christian
Re: Q: Adresse einer Methode
#308
Author: Thomas Neumann
Date: Thu, 24 Aug 1995 22:56
22 lines
1480 bytes
>>>>> "C" == Christian Horn <chorn@cip48.cscip.uni-sb.de> writes:

    C> Das Problem ist, dass ich zwar die Adresse von f2 erhalte
    C> (&A::f2), diese aber nicht nach void far* casten kann, um sie
    C> dann FP_SEG bzw. FP_OFF als Argument uebergeben zu koennen.


Ich kenne mich zwar mit dem DOS Segment-Krempel nicht aus, kann mir
aber vorstellen, worauf Du hinauswillst. Was Du vorhast, erfordert,
dass ein Memberfunction-Pointer in einen void* konvertierbar waere.
Das ist nicht der Fall, genauso wie man schon in ANSI-C nichtmal einen
normalen Funktionspointer einem void* zuweisen kann. Bei
Memberfunction-Pointern ist es noch wahrscheinlicher, dass es nicht
funktioniert, da ein MFP noch nichtmal unbedingt intern eine skalare
Repraesentation haben muss, er kann z.B. als Struktur aus einem
Pointer auf den vtbl der Klasse und einem Offset in diesen verwaltet
werden, wenn es sich um eine virtuelle Memberfunction handelt.

-t

-- 
PGP public key available, see <URL:http://www.ruhr.de/home/smart/start.html>
Re: Q: Adresse einer Methode
#334
Author: Reinhard Pfau
Date: Tue, 29 Aug 1995 07:06
58 lines
2270 bytes
Christian Horn (chorn@cip48.cscip.uni-sb.de) wrote:
: Hi,

: Es ist folgende Klasse gegeben:

: class A
: {
:    public:
:      void f1(void) {...}
:      void f2(void) {...}
: }

: Nun soll die Methode f1 die Adresse von f2 nehmen und sie mittels
: FP_SEG und FP_OFF in Segment und Offset zerlegen.

: Das Problem ist, dass ich zwar die Adresse von f2 erhalte
: (&A::f2), diese aber nicht nach void far* casten kann, um sie dann
: FP_SEG bzw. FP_OFF als Argument uebergeben zu koennen.

: Weiss jemand wie ich von der Methode f2 die Adresse erhalten kann, so
: dass ich sie zerlegen kann?

Ja, sowas brauchte ich auch mal. Leider hast du nicht angegeben,
welchen Compiler du benutzt. Daher folgende
WARNUNG: das folgende ist hochgradig TURBO-C++(3.00)-spezifisch und
ist daher _nicht_ unbedingt auf andere Compiler uebertragbar!!
Es entstand nach der TAE-Methode (Try-And-Error) unter Zuhilfenahme
der Assemblerquelltextgenerierung von TC++ (immer praktisch bei solchen
Problemen...).
So, und jetzt gehts los:

void A::f1 (void) {
  struct ptrCombi {
    void far* fkt;
    void far* ci;
  } mp;
  unsigned seg,ofs;

  *( (void (A::**)(void)) (&mp) ) = &A::f2;
  seg = FP_SEG(mp.fkt);
  ofs = FP_OFS(mp.fkt);
  // ---  mach was mit seg, ofs  ---
}

: Danke,
: Christian
Bitte, ich hoffe, es hilft. 
Ich nehme mal an, dass die anderen Borland-C++-Compiler intern aehnlich
arbeiten. Solltest du einen anderen Compiler benutzen, dann musst du
probieren.

  Reinhard.

 /-- Reinhard Pfau --- (ED-Pfau) --------------------------------------------\
| eMail: gz342@appl2.hrz.uni-siegen.de  |  IRC: Mubo  | no home-page         |
+----------------------------------------------------------------------------+
  "Programming is: Force the computer to do what _YOU_ want."  (rp)
  "Using M$-ware is the opposite!" 
Re: Q: Adresse einer Methode
#340
Author: Wolfgang Muees
Date: Tue, 29 Aug 1995 20:20
39 lines
1701 bytes
> Christian Horn (chorn@cip48.cscip.uni-sb.de) wrote:
> : Hi,
>
> : Es ist folgende Klasse gegeben:
>
> : class A
> : {
> :    public:
> :      void f1(void) {...}
> :      void f2(void) {...}
> : }
>
> : Nun soll die Methode f1 die Adresse von f2 nehmen und sie mittels
> : FP_SEG und FP_OFF in Segment und Offset zerlegen.
>
> : Das Problem ist, dass ich zwar die Adresse von f2 erhalte
> : (&A::f2), diese aber nicht nach void far* casten kann, um sie dann
> : FP_SEG bzw. FP_OFF als Argument uebergeben zu koennen.
>
> : Weiss jemand wie ich von der Methode f2 die Adresse erhalten kann, so
> : dass ich sie zerlegen kann?
>
[snip the rest]

Die Adresse einer Methode ist in der Regel zu nix nütze, es sei denn, es  
ist eine statische Methode (wo es ja geht). In der Regel ist es nicht C++ - 
Stil, die Adresse einer nicht-statischen Methode zu verwenden. In der  
Regel werden für solche Zwecke virtuelle Methoden verwendet. Deswegen  
würde mich wirklich interessieren, wozu das gut sein soll!

MFG
Wolfgang


--------------------------------------------------------------
> wolfgang@wmsickte.escape.de | Wolfgang Muees  +49-5305-685 <
>                             | Am Hohlweg 5, D-38173 Sickte <
--------------------------------------------------------------
## CrossPoint v3.02 ##
Re: Q: Adresse einer Methode
#352
Author: Reinhard Pfau
Date: Fri, 01 Sep 1995 07:32
44 lines
2659 bytes
Wolfgang Muees (wolfgang@wmsickte.escape.de) wrote:
: Hallo Reinhard,
[ DEL: Prob.: Adresse einer Memberfkt. & Frage, wozu ]
: > Wozu das gut sein soll?? Na, zum Bleistift fuer Callbacks!!
[ DEL: Beispiel, wo ich das schon benutzt habe ]

: Und warum - in 3 Teufels Namen - nimmst Du nicht eine statische
: Memberfunktion, die |ber einen abgespeicherten Zeiger auf die
: virtuelle Member-Funktion der Unterklasse zugreift? Das ist doch
: im Endeffekt genau dasselbe, nur ohne Krampf. Merken mu_t Du Dir
: den Zeiger auf das Objekt sowieso.

Hmm, ein LowLevel-Netzanalysetool oder Programme, die Netzdaten auf 
OSI-Ebene (ca.) 3 bearbeiten, hast du wohl noch nie programmiert??

Natuerlich kann ich in meine Basisklasse eine statische Memberfkt aufnehmen,
die als Callback dient. Nur muesste diese in meinen Fall eine Liste ver-
walten, die Paare von Zeigern enthaelt: Zeiger auf ECB und Zeiger auf die
Instanz, damit aus dem ECB-Zeiger (den meine Callback-Fkt als Parameter
bekommt) den Zeiger auf die Instanz bekommen kann. Das Durchsuchen einer
solchen Liste kostet aber Zeit; und da der Callback aus einer Interrupt-
routine erfolgt, habe ich die in meinem Fall nicht. Es ist halt wesentlich
schneller, den Callback _direkt_ zur richtigen Instanz umzuleiten. (Dort
muss ich zwar auch eine ECB-Liste fuehren, da mehrere Callbacks ausstehen
koennen, aber diese ist wesentlich kleiner und kann als array ausgefuehrt
sein, da man i.a. die benoetigte Groesse fuer eine bestimmte Instanz 
abschaetzen kann. In meiner Basisklasse wuesste ich nicht, wieviele
Instanzen wieviele Callbacks gleichzeitig ausstehen haben koennen.)

: > Ich hoffe, ich konnte dir ein Bild davon vermitteln, das es in der
: > Praxis doch Faelle gibt, wo man die Adresse einen Memberfunktion braucht.
: >
: Nein.
Evtl. jetzt..???  *hoff*

: >   mfg  Reinhard.
: MFG
: Wolfgang
 Reinhard.
--
 /-- Reinhard Pfau --- (ED-Pfau) --------------------------------------------\
| eMail: gz342@appl2.hrz.uni-siegen.de  |  IRC: Mubo  | no home-page         |
+----------------------------------------------------------------------------+
| In 1995, Win95 will work with bugs; but in 1996 it will not work at all!!  |
Re: Q: Adresse einer Methode
#351
Author: Reinhard Pfau
Date: Fri, 01 Sep 1995 07:46
50 lines
2566 bytes
Christian Horn (chorn@cip48.cscip.uni-sb.de) wrote:
: Reinhard Pfau (gz342@appl2.hrz.uni-siegen.de) wrote:
: : void A::f1 (void) {
: :   struct ptrCombi {
: :     void far* fkt;
: :     void far* ci;
: :   } mp;
: :   unsigned seg,ofs;
: : 
: :   *( (void (A::**)(void)) (&mp) ) = &A::f2;
: :   seg = FP_SEG(mp.fkt);
: :   ofs = FP_OFS(mp.fkt);
: :   // ---  mach was mit seg, ofs  ---
: : }

: Vielen Dank, das hat funktioniert (benutze Borland C++ 3.1).
: Koenntest Du den Code vielleicht kommentieren?

Naja, so viel zu kommentieren gibt's da eigentlich nicht.
Bei Borland/Turbo-C++ besteht ein Zeiger auf eine Memberfkt aus 2 Zeigern:

: Was bedeutet die Variable 'ci' in der Struktur?
Einen Zeiger auf die Adresse der Memberfkt und einem zweiten Zeiger,
ueber den ich nur eine Vermutung habe. (ci soll fuer "CurrentInstance"
stehen). Bei der Adresszuweisung wird der 2.Zeiger auf NULL gesetzt.

[SPEKULATION ON]
Ich nehme an, dass er bei 'normaler' Verwendung einer Funktionsvariable
beim Aufruf der Funktion den zugehoerigen this-Zeiger aufnimmt.
[SPEKULATION OFF]
Auf obige Struktur kam ich durch TAE (Try-And-Error); offiziell dokumentiert 
habe ich das noch nirgendwo gesehen.

Tja, und die Adresszuweisung ist einer der ueblichen Type-Casts, mit dem
man einem Compiler dazu bringt, einer Struktur einen dazu eigentlich
inkompatiblen Wert zuzuweisen (man castet einen Zeiger auf die Struktur
auf einen Zeiger der zuzuweisenden Struktur und dereferenziert das ganze).
WARNUNG: bei sowas sollte man genau wissen, was man macht; die Fehler-
moeglichkeiten sind sehr hoch, da man dabei die Typpruefung des Compilers
umgeht.

: Nochmals vielen Dank,
: Christian
 Gern geschehen. :)   Reinhard.
--
 /-- Reinhard Pfau --- (ED-Pfau) --------------------------------------------\
| eMail: gz342@appl2.hrz.uni-siegen.de  |  IRC: Mubo  | no home-page         |
+----------------------------------------------------------------------------+
  "Programming is: Force the computer to do what _YOU_ want."  (rp)
  "Using M$-ware is the opposite!" 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads