Oui, c'est facilement possible, dans les deux sens, si vous connaissez quelques astuces :
1) Le type "id" est en fait défini dans un en-tête C standard. Vous pouvez donc faire ce qui suit:
Dans votre en-tête :
#include
class MyWindow
{
public:
MyWindow();
~MyWindow();
protected:
id mCocoaWindow;
};
Dans votre implémentation (.mm) :
#include "MyWindow.h"
#include
MyWindow::MyWindow()
{
mCocoaWindow = [[NSWindow alloc] init];
}
MyWindow::~MyWindow()
{
[mCocoaWindow release];
mCocoaWindow = nil;
}
2) Il y a deux constantes de préprocesseur que vous pouvez utiliser pour exclure le code spécifique à C++/ObjC lorsqu'un fichier source les inclut, qui est l'une des deux, mais pas ObjC++ :
#if __OBJC__
// Le code ObjC va ici.
#endif /* __OBJC__*/
#if __cplusplus
// Le code C++ va ici.
#endif
Faites juste attention, vous ne pouvez pas simplement ajouter/supprimer des ivars ou des méthodes virtuelles avec un #ifdef, cela créera deux classes avec des mises en mémoire différentes et fera planter votre application de façon très étrange.
3) Vous pouvez utiliser un pointeur vers une structure sans déclarer son contenu :
Dans votre en-tête :
@interface MyCppObjectWrapper : NSObject
{
struct MyCppObjectWrapperIVars *ivars; // C'est directement ObjC, pas de ++.
}
@end
Dans votre fichier d'implémentation (.mm) :
struct MyCppObjectWrapperIVars
{
std::string myCppString1;
std::string myCppString2;
std::string myCppString3;
};
@implementation MyCppObjectWrapper
-(id) init
{
if(( self = [super init] ))
{
ivars = new MyCppObjectWrapperIVars;
}
return self;
}
-(void) dealloc
{
delete ivars;
ivars = NULL;
[super dealloc];
}
@end
Ceci rendra votre en-tête simple en C standard ou ObjC, tandis que votre fichier d'implémentation appelle les constructeurs/destructeurs de tous les ivars sans que vous ayez à créer/supprimer chacun en tant qu'objet sur le tas.
Tout cela concerne uniquement le côté Mac, mais cela signifierait que vous pourriez garder les éléments ObjC hors de vos en-têtes, ou du moins les rendre compilables lorsqu'ils sont utilisés à partir de fichiers clients multiplateformes de l'implémentation Mac de votre couche de portabilité C++.