6
votes

Pointeur de fonction de coulée en entier en C ++

J'ai une gamme d'entiers non signés qui doivent stocker des pointeurs vers des données et des fonctions ainsi que certaines données. Dans l'appareil, je travaille avec, la taille de pointeur est identique à la taille de l'INT non signé. Comment puis-je modifier le pointeur pour fonctionner dans Int non signé? Je sais que cela rend le code non portable, mais c'est un micro contrôleur spécifique. J'ai essayé ceci: xxx

mais cela me donne une erreur "conversion de type invalide"

la casser sur le pointeur vide et puis sur INT est en désordre. < PRE> XXX

Y a-t-il un moyen propre de le faire?

EDIT - Task_Ptr est le pointeur de la fonction VOID TASK_PTR (VOID) La réponse de l'amour Barmar prend ma portabilité. La matrice de pointeur de vide a également plus de sens que non signé Ints. Merci Barmar et Isaach1000.

Editer 2: Je l'ai eu, mon compilateur réfléchit un grand modèle de mémoire de sorte qu'il utilise des pointeurs 32 bits non 16 bits que je m'attendais à (petit micros avec la mémoire totale de 17k). < / p>

c++

6 commentaires

Vous ne pouvez pas faire le tableau un éventail de pointeurs vides?


Que diriez-vous d'utiliser une union de pointes de fonction et des pointeurs de données?


Un simple REINERPRET_CAST doit fonctionner aussi longtemps que (a) le type d'entier est suffisamment grand et (B) c'est un pointeur à une fonction normale (non membre ou statique). est-ce le cas ici? Qu'est-ce que task_ptr ?


Wow, barmar, qui rendrait mon code portable! C'est un cas majeur de la vision du tunnel de ma part. Merci un million, votre commentaire vaut 1000+


@ user1135541 N'oubliez pas que le syndicat Ntrick est toujours illégal, il est juste d'être soutenu par plus de compilateurs.


void (void) n'est pas un type de pointeur, c'est un type de fonction. Le type de pointeur correspondant est void (*) (void) .


3 Réponses :


4
votes

Une coulée de style C peut adapter une cheville octogonale dans un trou trapézoïdal, donc je dirais que cela compte tenu de votre quincaillerie et des exigences de cible extrêmement spécifiques, j'utiliserais ce casting, éventuellement enveloppé dans un modèle pour une plus grande clarté.

Alternativement, la double mise en forme sur vide * puis int a l'avantage de faire de la création du code comme un pouce endommagé afin que vos futurs mainteneurs sachent que quelque chose se passe et peut payer ATTENTION SPÉCIALE.

Modifier pour commentaires: Il apparaît que votre compilateur peut avoir un bogue. Le code suivant compile sur g ++ 4.5: xxx

EDIT2: Vous pouvez également souhaiter envisager d'utiliser le type intPTR_T au lieu de int . C'est un type d'intégration assez grand pour contenir un pointeur.


2 commentaires

Le compilateur C ++ renvoie une erreur lorsque j'utilise une erreur de style C: Error [PE171]: conversion de type invalide


Malheureusement, intPTR_T n'est pas spécifié pour permettre la reconstitution des pointeurs de fonction convertis comme il s'agit pour les pointeurs d'objet, et il n'y a pas d'équivalent pour les pointeurs de la fonction, soit :-(. Donc, il n'y a pas de moyen évident de Assurez-vous que votre code ne parviendra pas à compiler sur des systèmes où les pointeurs de fonction ne s'inscrivent pas dans intPTR_T .



-1
votes

Ceci est une conformité ANSI:

int MyFunc(void* p)
{
    return 1;
}

int main()
{
   int arr[2];
   int (*foo)(int*);

   arr[0] = (int)(MyFunc);

   foo = (int (*)(int*))(arr[0]);

   arr[1] = (*foo)(NULL);
}


3 commentaires

Essayé cela, mais mon C ++ se plaint, conversion de type invalide . Besoin d'une manière standard C ++ de le faire.


La dernière fois que j'ai vérifié, void principal () non standard.


J'utilise le Workbench Embedded iar. https://www.iar.com/fr/Products/iar-Egledded-workbench/ti-ms p430 / Mais je pense que je sais pourquoi cela ne fonctionne pas, il pense à une mémoire plus large Modèle alors j'utilise, ce qui rend les pointeurs 20bit au lieu de 16. Donc, oui, vous avez raison, c'est le problème du compilateur. Le compilateur MINGW n'a aucun problème.



2
votes

en C ++ Un pointeur peut être converti en une valeur d'un type d'intégration suffisamment grand pour le maintenir. Le type std :: intptr_t code> est défini de telle sorte que vous puissiez convertir un Void * code> sur intptr_t code> et retour pour obtenir la valeur d'origine. Si void * code> a une taille égale ou supérieure à celle des pointeurs de fonction sur votre plate-forme, vous pouvez faire la conversion de la manière suivante.

#include <cstdint>
#include <cassert>

void foo() {}

int main() {
    void (*a)() = &foo;

    std::intptr_t b = reinterpret_cast<std::intptr_t>(a);

    void (*c)() = reinterpret_cast<void(*)()>(b);
    assert(a==c);
}


1 commentaires

Il est également supporté de manière conditionnelle si a peut être réinterpret-couler sur B , même si intptr_t existe. (Cependant, il est garanti que si ce support existe, alors a == C ).