Question

Je dois convertir les pointeurs en long (SendMessage ()) et je veux vérifier en toute sécurité si la variable est correcte de l’autre côté. Je pensais donc à dynamic_cast mais cela ne fonctionnerait pas avec des classes qui ne sont pas virtuelles. Alors j'ai pensé à faire typeid mais cela fonctionnera jusqu'à ce que je passe une variable dérivée comme base.

Existe-t-il un moyen de vérifier si le pointeur correspond à ce que j'attendais de l'exécution? Existe-t-il un moyen d'utiliser typeid pour voir si un pointeur est un type dérivé d'une base particulière?

Était-ce utile?

La solution

Si tout ce que vous avez est un long, alors vous ne pouvez pas vraiment faire grand chose. Il n'y a pas de moyen général de déterminer si un nombre arbitraire représente une adresse mémoire valide. Et même si vous savez que c'est une adresse mémoire valide, il n'y a aucun moyen de déterminer le type d'objet pointé par le pointeur. Si vous ne pouvez pas être sûr du type réel de la chose avant que son adresse ait été convertie en <=>, alors vous ne pouvez pas être sûr qu'il sera sécuritaire de transtyper le <=> quel que soit le type que vous envisagez de diffuser. à.

Vous devrez simplement vous assurer que l'expéditeur du message vous a envoyé une valeur valide. Le mieux que vous puissiez faire est de prendre certaines précautions pour réduire les conséquences pour votre propre programme lorsque celui-ci reçoit une valeur factice.

Autres conseils

Votre référence à SendMessage() donne l'impression que MS Windows est votre plate-forme, puis La règle d'utilisation des pointeurs (Windows) est une lecture recommandée. Il détaille les PtrToLong et PtrToUlong fonctions et autres éléments fournis par Microsoft dans des situations comme celle-ci.

Vous ne pouvez pas utiliser typeid. Il en résultera une violation d'accès si vous obtenez des ordures au lieu d'un pointeur valide, votre vérification est donc absurde.

Ce que vous devez faire est d’envelopper votre SendMessage et le code qui traite le message dans une seule interface sécurisée. De cette façon, vous ne pourrez pas transmettre d’effets inattendus à SendMessage et n’aurez besoin d’aucun contrôle de la part du destinataire.

Le système de types C ++ fonctionne au moment de la compilation. Une fois que vous avez lancé un pointeur sur un long, vous perdez toutes les informations de type. Un long est juste beaucoup de bits en mémoire; vous ne pouvez pas identifier qu'il pointe vers un objet.

PTLib ( http://sourceforge.net/projects/opalvoip/ ) utilise un fichier PCLASSINFO macro pour définir les relations entre les classes. Ceci fournit des fonctions comme IsDescendant et GetClass.

Vous pourriez probablement mettre en œuvre quelque chose de similaire.

dynamic_cast fonctionne en vérifiant la signature de la table de méthode virtuelle. Si vous n'avez pas de méthodes virtuelles, vous n'avez pas de VMT, aussi, comme vous dites, dynamic_cast ne fonctionnera pas. Cependant, si vous n'avez pas d'IMT, vous n'avez absolument AUCUNE connaissance de l'objet pointé.

La meilleure chose à faire est d'exiger que les pointeurs se dirigent vers les classes avec au moins une méthode virtuelle, même s'il s'agit d'un mannequin. Le casting dynamique fonctionnera alors.

Je ne comprends pas encore en quoi consiste votre question.

  • Si vous voulez ou non être sûr que le fait de lancer un long et arrière donnera la même valeur, regardez Vérification en toute sécurité du type d'une variable
    Compte tenu des & Quot; Règles d'utilisation des pointeurs & Quot; MS-Site est l’autre répondeur lié, le bon type de transtypage est UINT_PTR. Ainsi, vous UINT_PTR v = reinterpret_cast<UINT_PTR>(ptr); transtypez en un type intégral et inversez-le pour le renvoyer à nouveau au pointeur. La norme C ++ garantit la restauration de la valeur d'origine. (Voir le lien que j'ai donné ci-dessus pour mon explication à ce sujet). Le site de Microsoft dit d'ailleurs que WPARAM et LPARAM changent de taille en fonction de la plate-forme. Donc, vous pouvez simplement utiliser cette variable v et SendMessage la.
  • Si c'est le moyen de vérifier de l'autre côté si le pointeur (converti en un type de pointeur) pointe sur un objet, la réponse est vous ne pouvez pas . Comme vous ne savez apparemment pas quel type de pointeur a été utilisé pour l’envoyer, vous ne pouvez pas vérifier du côté de la réception le type de type dynamique indiqué par le pointeur. Si vous connaissez le type du pointeur du côté de l'expéditeur, votre chèque ne sera pas requis en premier lieu.

Sous Windows, MFC fournit une méthode permettant de vérifier si un pointeur donné pointe vers un emplacement mémoire valide (cela se fait par recouvrement d'un segfault). Je ne me souviens pas du nom de la fonction, mais c'est là. Néanmoins, cela ne garantit pas que le contenu de la mémoire pointée est valide. Il se peut que VMT soit toujours invalide et que votre code plante. Bien sûr, vous pouvez vous-même piéger le segfault ( voir MS Knowledge Base )

Pour vérifier si quelque chose appartient à un type, vous devez commencer par une classe de base. Si vous créez le destructeur de la classe de base & "Virtual &", Toutes les classes dérivées auront des VMT.

Si vous devez absolument éviter VMT, vous devez disposer d’une sorte de discriminateur vous indiquant le problème, comme le type d’événement dans les événements MS Windows.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top