[Résolu] Objective-C++: problèmes d'includes

6ix6ix Membre
décembre 2009 modifié dans API UIKit #1
Hello,

Le sujet a déjà  été abordé, mais j'ai toujours des problèmes... d'où ma demande d'aide.  :P

Je souhaite utiliser sur un projet iPhone plusieurs classes écrites en C++, qui sont utilisées par quelques classes Objective-C, de la sorte:
  • Vector2D [C++]
  • Vector3D [C++] => #include Vector2D
  • Projection [C++] => #include Vector2D + Vector3D
  • Annotation [Objective-C++] : une des variables d'instance est un Vector3D
  • Point [Objective-C++] : une des variables d'instance est un Vector3D


Mes classes C++ sont "entourées" de #ifndef/#define avant les #include et mes classes Annotation et Point sont enregistrées en ".mm".

Sauf que lorsque j'essaie d'utiliser ces classes C++ dans dans les classes Objective-C++, je me retrouve avec des erreurs "Expected specifier-qualifier-list before 'Vector3'" sur les variables de type Vector3, et des erreurs "Expected '=', '.', ..., before 'Vector3'" dans mon Vector3D.h.

J'ai beau essayer dans tous les sens de résoudre ce problème, impossible! Ce que j'essaie est-il vraiment possible?? Y a-t-il une manière claire d'éviter ces problèmes de link ?

Réponses

  • erisereriser Membre
    06:58 modifié #2
    Hello tu dois renommer les fichiers .m qui utilisent des classes c++ de  en .mm

  • 6ix6ix Membre
    06:58 modifié #3
    dans 1260217118:

    Hello tu dois renommer les fichiers .m qui utilisent des classes c++ de  en .mm


    Merci, mais...

    dans 1260197415:
    Mes classes C++ sont "entourées" de #ifndef/#define avant les #include et mes classes Annotation et Point sont enregistrées en ".mm".


    Cela dit, je m'oriente plutôt vers une solution " intermédiaire ": définir des classes " wrapper " pour mes Vector sous forme de classes Objective-C++, contenant elles-mêmes des instances ainsi que des méthodes vers les classes C++. Ainsi mes classes Annotation et Point ne traitent qu'avec de l'Objective-C.

    Par contre je connais peu C++ et n'ai jamais mélangé ainsi les deux langages, je nage donc un peu, ne sachant pas vraiment quelles sont les bonnes pratiques, notamment au niveau des #include ou de la séparation des classes.  :(
  • erisereriser Membre
    06:58 modifié #4
    Attention il faut aussi renommer en .mm les fichiers qui utilisent Annotation et Point puisqu'il utilisent du C++ .

    Ce n'est pas un problème de link c'est juste que le compilateur pense parser de l'objC alors que c'est de l'objc++

    En gros la règle pour ne pas te prendre la tête si tu mixe du c++ avec de l'objective C: utilise toujours comme extension .mm
  • 6ix6ix Membre
    06:58 modifié #5
    Justement, ici je n'ai pas vraiment envie de tout passer en .mm; j'utilise ces classes C++ uniquement pour une petite partie et parce qu'elles sont également utilisées dans une autre application, totalement C++: ça permet d'avoir un "miroir" entre les deux tout en évitant de tout réécrire en Objective-C.

    Le fait d'encapsuler une classe Vector C++ dans une classe VectorWrapper Objective-C++ (.mm) devrait donc me permettre de bien garder cette séparation, non? Cela rajoute une couche intermédiaire, mais évite aux classes Objective-C d'avoir connaissance du traitement C++-
  • mpergandmpergand Membre
    06:58 modifié #6
    Et si tu utilises des pointeurs pour ces variables C++, ça donne quoi ?


  • 6ix6ix Membre
    06:58 modifié #7
    dans 1260271090:

    Et si tu utilises des pointeurs pour ces variables C++, ça donne quoi ?


    J'ai tout essayé, pointeur ou pas, même résultat. ;)

    Mais finalement là  je crois que je m'en sors en faisant de la sorte: ma classe Vector.mm contient les coordonnées x, y et z, qui sont accessibles en tant que propriétés, et dispose de méthodes "encapsulant" les méthodes C++. Exemple: une méthode d'addition de vecteur, qui utilisera les classes C++ nécessaires (d'après les x, y, z) afin de faire l'addition.

    Donc je pense avoir une solution à  mon problème, même si je n'ai pas forcément compris ce qui ne marchait pas dans ma version initiale  :-\\

  • erisereriser Membre
    décembre 2009 modifié #8
    Désolé pour le retard beaucoup de taf en ce moment.

    Si tu veux wrapper et caché ton implémentation c++ alors utilise des void* coté header et des casts a outrance dans ton .mm

    exemple:

    VectorWrapper.h
    <br /><br />// note pas d&#39;include de ton fichier vector.h (c++) <br /><br />@interface VectorWrapper : NSObject {<br />	void* vector; // void* opaque <br />}<br /><br />- (float) length;<br />- (float) x;<br />- (float) y;<br />.... etc <br />
    


    VectorWrapper.mm

    <br /><br /><br />#import &quot;VectorWrapper.h&quot;<br />#include &quot;Vector.h&quot; // ton header C++<br /><br />@implementation VectorWrapper<br /><br /><br />-(id) init<br />{<br />	self = [super init];<br />	vector = new Vector2d;<br /><br />	return self;<br />}<br /><br />#define vec ((Vector2d*)vector)&nbsp; // pas super propre ... <br /><br />-(void) dealloc<br />{<br />	delete vec;<br />	[super dealloc];<br />}<br /><br />-(float) x<br />{<br />	return vec-&gt;x;<br />}<br /><br />-(float) y<br />{<br />	return vec-&gt;y;<br />}<br /><br />-(float) length<br />{<br />	return vec-&gt;length();<br />}<br /><br />#undef vec<br /><br />@end<br /><br /><br />
    




    voilou, pour ma pars je fais plutôt l'inverse l'ensemble de mon code est en C++ et la gui en objc/Cocoa sous mac et C#/.NET sous Windows 


  • 6ix6ix Membre
    06:58 modifié #9
    Merci cette réponse.

    J'ai finalement obtenu ce que je voulais, sans utiliser de wrapper. J'ai tout repris un à  un, et du coup il est difficile de dire ce qui ne fonctionnait pas auparavant...

    Si cela peut aider quelqu'un d'autre, voici ce que j'ai fait (je ne dis pas que c'est le mieux à  faire):

    (*) Mes classes C++ (Vector) sont donc en C++ "pur", dont les header (.h) sont "entourés" des #defines suivant:
    <br />#ifdef __cplusplus<br /><br />#ifndef _VECTOR_H<br />#define _VECTOR_H<br /><br />[...]<br /><br />#endif /* _VECTOR_H */<br /><br />#else<br />typedef struct Vector__ Vector;<br />#endif<br />
    


    (*)Mes classes Objective-C++ (Annotation,...), de type .mm, possèdent plusieurs variables d'instances, dont certaines de type Vector (C++), déclarées en tant que pointeurs (avec un #import "Vector.h").

    (*)Une classe utilisant un objet Objective-C++ est donc également en Objective-C++.
Connectez-vous ou Inscrivez-vous pour répondre.