objet de classe cast en objet struct C / C ++

Nov 27 2020

J'ai deux projets l'un en C et l'autre en C ++ et j'essaie de convertir un objet de classe en C ++ en un objet de structure en C.Par exemple, j'ai un objet de myClass que j'essaye de convertir en myStru comme suit:

Dans mon projet C ++, j'ai cette classe:

class myClass{
    myClass();
    ~myClass();
    char    *data;
    int     var;
}

Dans mon projet C, j'ai cette structure:

struct myStru {
    char  *data;
    int    var;
};
typedef struct myStru myStru;

Maintenant, dans mon projet C ++, je crée un objet à partir de myClass:

myClass *classObj = new myClass();
classObj->data = new char[10];
classObj->var  = 99;

Dans mon projet C, je reçois en classObjtant que pointeur vide et j'essaye de le caster comme suit:

myStru *struObj = (myStru*)malloc(sizeof(struct myStru));
struObj = (myStru*) classObj;
printf(" struObj->var %d \n", struObj->var); // this print 99

Je le fais plus tard dans mon projet C ++

   delete []classObj->data; // I know smart pointers can be used here but this is not my point in this question now
    delete  classObj;

Est-ce que ce que je fais ici est correct? c'est-à-dire, en jetant classObjde struObjcette façon?

L'exemple complet peut être trouvé ici (merci @Borgleader) http://coliru.stacked-crooked.com/a/05543b944ee23f2f

EDIT: J'ai trouvé une bonne réponse à ma question dans cet article (voir Accéder aux classes C ++ à partir de C): https://www.oracle.com/technical-resources/articles/it-infrastructure/mixing-c-and-cplusplus.html

Réponses

3 BartekBanachewicz Nov 27 2020 at 13:22

Je ne suis pas sûr à 100%, car c'est du C ++ et vous ne pouvez jamais l'être, mais je pense que ce n'est pas un comportement défini.

Vous ne pouvez pas accéder aux membres d'une structure via un pointeur vers un membre vers une autre structure. Une exception notable à cette règle consiste à accéder à la séquence initiale commune de deux structures membres d'une union.

Cela pourrait fonctionner si vous héritiez en fait de votre classe de la structure à la place.

Alternativement, l'autre exception est que vous pouvez en toute sécurité memcpyentre ces structures, AFAIR.

1 Persixty Nov 27 2020 at 17:08

Cette question concerne l'interopérabilité et vous n'obtiendrez jamais de réponse définitive car elle repose sur des aspects définis par l'implémentation du compilateur C et C ++. Les structet les classsont des types compatibles avec la mise en page en termes C ++. Il est très clair que déclarer un a classet un a structn'est pas un problème et parce qu'ils ont tous les deux le même accès aux membres pour tous leurs membres (bien que différents les uns des autres) sont compatibles (au moins en C ++ 14, je crois) .

Le mieux que la norme va offrir est:

Remarque: les classes de mise en page standard sont utiles pour communiquer avec du code écrit dans d'autres langages de programmation. Leur disposition est spécifiée en 12.2. - note de fin

L' intention est que ces classes (qui sont à la fois compatibles avec la disposition standard et la disposition) soient interopérables. Si vous utilisez le même compilateur dans deux modes, il serait «décevant» si cela ne fonctionnait pas. Mais c'est le mieux que vous soyez «décevant» - consultez la documentation.

Je m'interroge un peu sur la gestion des ressources dans la stratégie globale. Vous avez déclaré un destructeur dans le C ++ classet c'est bien ce n'est pas le cas virtual!), Mais vous le copiez dans un structcôté C, si le code C a une fonction `` destructor like '' pour détruire ses objets, ce qui peut entraîner des J'ai cloné l'objet C ++ au niveau du bit (espérons-le!).

Si C appelait free(s->data)sa copie d'un objet construit en C ++ qui avait utilisé, newvous provoquiez un comportement indéfini. Cela pourrait être le cas exceptionnel qui justifie l'utilisation malloc()du côté C ++ pour la compatibilité.

Donc, c'est probablement OK, mais vous comptez sur les capacités d'interopérabilité entre C et C ++ et les deux normes vous mènent aussi loin que possible, mais par définition, vous utilisez des fonctionnalités définies par l'implémentation.

Par cette note, nous savons que la norme est prête à fonctionner et elle le fera probablement. Bonne chance!