Newsgroup: it.comp.lang.c++
Titolo: Indirizzo metodo di una classe

Salve a tutto il NG,
ho un piccolo problema e non so come venirne a capo.
Ho una classe con un metodo:
class MyClass{
    Method();
};
Questo metodo non puo' essere static, e io ho bisogno di
conoscere il suo indirizzo in memoria. Non posso neanche
fare un puntatore a funzione, perche' non posso sapere
a priori quali parametri prendera' il metodo, se uso static
e faccio una cosa simile:
void *p = (void *)&MyClass::Method;
Funziona, ma se non lo metto come static il VC7 mi da errore e
neache con reinterpret_cast sono riuscito ad ottenere quell'indirizzo
di memoria. Esiste un metodo alternativo? Devo solo sapere a che
indirizzo si trova il primo byte del metodo, e questo problema mi
sta mettendo in seria difficolta' :)
Vi ringrazio molto per l'aiuto :))))

 conoscere il suo indirizzo in memoria. 
class MyClass
{
public:
     void Method();
};
void (MyClass::*pointer)() = &MyClass::Method;
-- 
si prepara direttamente nel bicchiere basso detto "tumbler basso". Tre o 
quattro cubetti di ghiaccio, aggiungere il gin, il martini rosso, il 
bitter campari e mescolare. Guarnire con una fetta d'arancia.

 di memoria. Esiste un metodo alternativo?
Non esiste un metodo portabile nel linguaggio C++.
-- 
Horst

Quello che vuoi fare non  e' possibile e cosi' come l'hai spiegato non
ha neanche molto senso. Forse e' meglio se descrivi il tuo problema
piuttosto che il tentativo di soluzione.
Ciao,
Nicola

Non ho spiegato il problema solo per essere sintetico, in
realta' ha senso, altrimenti non starei cercando di farlo.
Nella classe ho un metodo che mi riempie una lista, ogni
membro della lista ha un puntatore e questo puntatore
deve essere inizializzato con l'indirizzo di un membro della
classe. L'indirizzo del membro mi serve perche' ho bisogno
di assemblare un jmp assoluto e inserirlo in quell'indirizzo,
ovviamente per il calcolo del jmp ho bisogno di conoscere
l'indirizzo di destinazione, che deve essere appunto uno
dei metodi della mia classe. Quello che sto cercando di fare
e' un hook, in C ovviamente funziona alla grande, ma volevo
farmi una libreria in C++ per rendere le cose piu' agevoli,
solo che non potendo rendere statico il membro, non ho idea
di come ottenere l'indirizzo del metodo e mi sembrava quantomeno
strano che non ci fosse una via d'uscita :(.
Ah il metodo indicato da Fred l'avevo gia' provato ma purtroppo
non funziona, a me non interessa che sia portabile, anche un
metodo non portabile andrebbe benissimo, tanto la lib deve funzionare
esclusivamente su windows.
Esistono altre soluzioni? L'utilizzo di un template potrebbe aiutarmi?
Grazie ancora per le risposte e buona giornata.

Prima di tutto una domanda: come fai a chiamare la funzione di cui
intendi salvare l'indirizzo se come hai scritto non ne conosci il tipo?
Di solito in questi casi si adotta almeno una convenzione sul prototipo
delle funzioni da chiamare e quindi si opera con un tipo di funzione
ben definito, si tratti di funzioni libere, funzioni membro statiche o
funzioni membro normali.
Tra l'altro una volta definita la segnatura delle funzioni da chiamare
puoi anche generalizzare il discorso, ovvero gestire indifferentemente
i diversi tipi di funzione, tramite una libreria tipo Boost.Function
(vedi 
http://www.boost.org
)
Nota poi che qualsiasi funzione membro puo' essere semplicemente
trasformata in una funzione membro statica in modo molto semplice:
class C {
  int f() { return 42; }
  static int g(C & c) { return c.f(); }
};
A meno che tu non abbia vincoli di prestazioni drammaticamente
stringenti.
Resta comunque la sensazione che stai prendendo una strada molto
complicata per fare qualcosa per la quale potrebbero esistere approcci
piu' semplici.
Ciao,
Nicola

"Bonzo_idd" <bonz...@REMOVEhotmail.com> ha scritto nel messaggio 
news:d1bsm8$fi6$1...@balena.cs.interbusiness.it...

Secondo me stai sbagliando l'approccio.
Devi isolare il caso così da capire cosa ti serve in dettaglio .
Per quel che so io in c++ (parlando di OO ovviamente) queste cose si evitano 
e si cercano delle soluzioni come dire
più ha oggetti adesso nel caso specifico non so se può esserti utile ma al 
posto dei puntatori a funzione per il tuo caso potresti usare il pattern
observer (veditelo se non lo conosci)
Poi devi conoscere bene il linguaggio altrimenti fare in misc di c/c++ non 
conoscendo bene uno o l'altro diventa un macello
p.s
i miei sono solo consigli... non ho esaminato a a fondo il tuo problema.
buon lavoro ciao.

Ciao di nuovo,
avete entrambi ragione, il problema e' che non trovo una soluzione
differente da questa, vi spiego meglio il problema:
devo riempire una struttura con l'indirizzo del metodo (in C e' semplice, in
C++ a quanto pare no), il motivo e' presto detto, devo leggere in
memoria il codice di un programma (programma in generale, non
specifico) cercare determinate istruzioni (per fare un hook su alcune
chiamate)
e sostituirle in modo che il suo codice venga dirottato, per far questo devo
letteralmente assemblare un jmp o una call al mio indirizzo, di modo che
l'esecuzione
arrivi sotto il mio controllo, non avevo esposto il problema in precedenza
perche'
e' OT con il NG.
Allora in C cosa faccio, trovo il codice, assemblo il jmp e gli dico:
jmp &Call (&Call e' l'indirizzo della funzione creata da me)
presto fatto, se il prototipo della mia funzione e' uguale al prototipo
della
chiamata allora posso accedere normalmente allo stack e fare cio' che
voglio.
Tutto questo funziona egregiamente in C, ci vuole piuttosto poco a dire al
prog
di saltare nella mia routine visto che conosco l'indirizzo.
Poi mi e' venuta la malsana idea di fare una lib in C++ che mi gestisse gli
hook,
l'ho progettata benino... non considerando il problema esposto qualche post
fa ;p.
Ed ora non ho soluzioni alternative, perche' il jmp devo tassativamente
assemblarlo,
e per far questo ho bisogno di conoscere l'indirizzo del metodo, potrei
farlo statico,
ma in questo modo mi precluderei l'utilizzo degli altri metodi della classe
e quindi
tutto lo sforzo sarebbe inutile :)))))
Mi rendo conto che utilizzare il C++ per fare operazioni cosi a basso
livello non sia
un'idea grandiosa, ma siccome mi avrebbe risparmiato un bel po' di lavoro
avevo
deciso di provare :).
Grazie a tutti per la grande disponibilita' :)