Domanda

Ho bisogno di convertire i puntatori in long (SendMessage ()) e voglio verificare in sicurezza se la variabile è corretta sul lato opposto. Quindi stavo pensando di fare dynamic_cast ma che non funzionerà su classi che non sono virtuali. Poi ho pensato di fare typeid, ma funzionerà fino a quando passo una var derivata come base.

Esiste un modo per verificare se il puntatore è quello che mi aspetto durante l'esecuzione? C'è un modo in cui posso usare typeid per vedere se un puntatore è un tipo derivato da una base particolare?

È stato utile?

Soluzione

Se tutto ciò che hai è un long, non c'è davvero molto che puoi fare. Non esiste un modo generale per determinare se un numero arbitrario rappresenta un indirizzo di memoria valido. E anche se sai che è un indirizzo di memoria valido, non c'è modo di determinare il tipo di cosa a cui punta il puntatore. Se non puoi essere sicuro del tipo reale della cosa prima che il suo indirizzo fosse castato su <=>, allora non puoi essere sicuro che sarà sicuro lanciare il <=> su qualunque tipo tu preveda di trasmettere a.

Devi solo fidarti che il mittente del messaggio ti ha inviato un valore valido. Il meglio che puoi fare è prendere alcune precauzioni per ridurre le conseguenze per il tuo programma quando riceve un valore falso.

Altri suggerimenti

Il tuo riferimento a SendMessage() fa sembrare che MS Windows sia la tua piattaforma e quindi Regole per l'utilizzo di puntatori (Windows) . Descrive in dettaglio le funzioni PtrToLong e PtrToUlong e altre cose che Microsoft fornisce in situazioni come questa.

Non puoi usare typeid. Se si ottiene immondizia invece di un puntatore valido, si verificherà una violazione di accesso, quindi il controllo è privo di senso.

Quello che dovresti fare è racchiudere SendMessage e il codice che elabora il messaggio in un'unica interfaccia sicura. In questo modo non sarai in grado di passare cose inaspettate a SendMessage e non avrai bisogno di alcun controllo sul lato ricevente.

Il sistema di tipo C ++ funziona al momento della compilazione. Dopo aver lanciato un puntatore a lungo, perdi tutte le informazioni sul tipo. Un lungo è solo così tanti bit in memoria; non è possibile identificare il fatto che puntava a un oggetto.

PTLib ( http://sourceforge.net/projects/opalvoip/ ) utilizza un PCLASSINFO macro per definire le relazioni tra le classi. Questo fornisce funzioni come IsDescendant e GetClass.

Probabilmente potresti implementare qualcosa di simile.

dynamic_cast funziona controllando la firma della tabella dei metodi virtuali. Se non hai metodi virtuali, non hai VMT, quindi, come dici, dynamic_cast non funzionerà. Tuttavia, se non si dispone di VMT, non si ha assolutamente alcuna conoscenza sull'oggetto indicato.

La tua scommessa migliore è richiedere che i puntatori siano a classi con almeno un metodo virtuale, anche se è un manichino. Il cast dinamico funzionerà quindi.

Non ho ancora capito di cosa tratta la tua domanda.

  • Se è possibile essere certi che il casting su long e back produrrà lo stesso valore, visualizzare Verifica sicura del tipo di una variabile
    Dato il & Quot; Regole per l'uso dei puntatori & Quot; Sito MS a cui è collegato l'altro Risponditore, il tipo giusto su cui eseguire il cast è UINT_PTR. Quindi fai UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr); per eseguire il cast in un tipo integrale e fai il contrario per ricondurlo nuovamente al puntatore. Lo standard C ++ garantisce il ripristino del valore originale. (vedi il link che ho dato sopra per la mia spiegazione di questo). Quel sito Microsoft dice anche che WPARAM e LPARAM cambiano le loro dimensioni a seconda della piattaforma. Quindi potresti semplicemente usare quella variabile v e SendMessage.
  • Se è come puoi verificare dall'altra parte se il puntatore (convertito in un tipo di puntatore) punta o meno ad un oggetto, la risposta è non puoi . Poiché apparentemente non si è sicuri del tipo di puntatore utilizzato per inviarlo, non è possibile verificare sul lato ricevente il tipo dinamico a cui punta il puntatore. Se conosci il tipo che il puntatore aveva sul lato del mittente, il tuo controllo non sarebbe richiesto in primo luogo.

In Windows, MFC fornisce un metodo per verificare se un determinato puntatore punta a una posizione di memoria valida (ciò avviene eseguendo il trapping segfault). Non ricordo il nome della funzione, ma è lì. Tuttavia, non garantisce che il contenuto della memoria indicato sia valido. Potrebbe ancora avere VMT non valido e bloccare il codice. Naturalmente, puoi intercettare tu stesso il segfault ( consulta MS Knowledge Base )

Per verificare se qualcosa appartiene a un tipo, è necessario disporre di una classe base per iniziare. Se si crea il distruttore della classe base & Quot; virtuale & Quot; tutte le classi derivate avranno VMT.

Se devi evitare VMT a tutti i costi, devi avere una sorta di descrittore che ti dica con cosa hai a che fare, come il tipo di evento negli eventi di MS Windows.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top