2010-04-26 16 views
40

Sto provando a mescolare Objective-C con C++. Quando compilo il codice, ottengo diversi errori.Mixing Objective-C e C++

A.h

#import <Cocoa/Cocoa.h> 
#include "B.h" 

@interface A : NSView { 
    B *b; 
} 

-(void) setB: (B *) theB; 

@end 

a.m

#import "A.h" 

@implementation A 

- (id)initWithFrame:(NSRect)frame { 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code here. 
    } 
    return self; 
} 

- (void)drawRect:(NSRect)dirtyRect { 
    // Drawing code here. 
} 

-(void) setB: (B *) theB { 
    b = theB; 
} 

@end 

B.h

#include <iostream> 

class B { 

    B() { 
     std::cout << "Hello from C++"; 
    } 

}; 

Qui ci sono gli errori:

/Users/helixed/Desktop/Example/B.h:1:0 /Users/helixed/Desktop/Example/B.h:1:20: error: iostream: No such file or directory 
/Users/helixed/Desktop/Example/B.h:3:0 /Users/helixed/Desktop/Example/B.h:3: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'B' 
/Users/helixed/Desktop/Example/A.h:5:0 /Users/helixed/Desktop/Example/A.h:5: error: expected specifier-qualifier-list before 'B' 
/Users/helixed/Desktop/Example/A.h:8:0 /Users/helixed/Desktop/Example/A.h:8: error: expected ')' before 'B' 
/Users/helixed/Desktop/Example/A.m:26:0 /Users/helixed/Desktop/Example/A.m:26: error: expected ')' before 'B' 
/Users/helixed/Desktop/Example/A.m:27:0 /Users/helixed/Desktop/Example/A.m:27: error: 'b' undeclared (first use in this function) 
+2

Non dimenticate che si forza gli utenti della vostra classe objC a usa ObjC++ se inserisci C++ include nell'intestazione - usa i puntatori opachi per evitarlo. –

+0

@ gf Quindi, come raccomanderesti di farlo? Dovrei semplicemente usare un puntatore void o posso usare un id? – LandonSchropp

+1

Per evitare di perdere la sicurezza del tipo personalmente preferisco le strutture dichiarate in avanti (http://stackoverflow.com/questions/2262011/adding-c-object-to-objective-c-class/2262395) ma ho anche visto * "private" * Classi ObjC (cioè tramite variabili di istanza 'id'). –

risposta

73

È necessario denominare i file .m.mm. E sarete in grado di compilare codice C++ con Objective-C.

Così, seguendo il tuo esempio, il tuo AView.m file deve essere nominato AView.mm. È semplice. Funziona molto bene. Io uso un sacco di contenitori std (std :: vector, std :: queue, ecc.) E il codice C++ legacy nei progetti iPhone senza complicazioni.

+0

Che cosa è impossibile rinominare il file .m in .mm a causa di altre classi che segnaleranno un errore se utilizzo l'estensione .mm. Qualche altra soluzione è la mente? – Scar

5

Non importa, mi sento stupido. Tutto quello che devi fare è rinominare AView.m in AView.mm in modo che il compilatore sappia che è Objective-C++ e si compila senza problemi.

+2

Sono contento che sia stato così semplice, dato che ora posso usare il TUO codice come modello per provare questa merda! – Teekin

+1

C'è un altro modo per farlo - nella finestra degli attributi del file (dimenticare come si chiama - la finestra di destra quando si fa clic su un file in Navigator) è possibile impostare il tipo di file indipendentemente dalla sua estensione di file. –

2

si potrebbe tenere il pulitore di interfaccia con la dichiarazione anticipata di classi C++:

#import <AnObjCclass.h> 
class DBManager; // This is a C++ class. NOTE: not @class 

@interface AppDelegate : UIResponder <UIApplicationDelegate, 
            CLLocationManagerDelegate, 
            MFMailComposeViewControllerDelegate> 
{ 
    DBManager* db; 
... 
} 
+3

Questo non risponde alla domanda. Riguarda lo stile del codice e non ha nulla a che fare con gli errori del compilatore riportati nella domanda. Dovrebbe essere un commento. –

0

Nelle situazioni in cui si desidera introdurre una semplice funzione C++ come std::cout << Licks poi caldo offre una buona alternativa.

cambiare il "Identity and Type" Da: Objective-C source A: Objective-C++ source

L'estensione .mm identifica semplicemente il tipo di file; e quindi stai cercando un Objective-C++ non un tipo Objective-C.

1

Sto condividendo alcuni dei punti che ho capito su questo argomento.

Possiamo mescolare entrambi i file .cpp e .m con un'interfaccia C pura. Come sappiamo, il compilatore Clang supporterà C++, Objective C e Objective C++, potrebbe essere un modo migliore per mescolare questi linguaggi.

Una cosa quando si mescolano questi linguaggi per essere curati è usare i file di intestazione. Possiamo mantenere il C++ fuori dalle intestazioni Objective C dichiarando gli oggetti Cpp nelle estensioni di classe.

In alternativa, è possibile dichiarare gli oggetti cpp proprio all'inizio del blocco @implementation nel nostro file Objective Cpp (.mm).

La gestione della memoria sarà un problema quando ci occupiamo di oggetti Cpp. Possiamo allocare memmory per un oggetto usando 'new' e rilasciare la memoria chiamando 'delete object'. Normalmente se stiamo usando ARC, non dobbiamo essere consapevoli di rilasciare la memoria per un oggetto.

Mentre si utilizzano le classi cpp, è possibile dichiarare un oggetto Cpp in due modi: wrapper CppWrapper e wrapper CppWrapper * in cui CppWrapper è una classe Cpp. Quando utilizziamo quest'ultimo, il programmatore è responsabile della gestione della memmory. Un'altra cosa importante è che quando chiamiamo un metodo C oggettivo con parametri, stiamo passando i riferimenti, mentre in cpp dobbiamo passare i parametri per riferimento usando la parola chiave '&', altrimenti copia dell'oggetto è stato passato.

La deallocazione dell'oggetto Objective C viene gestita in fase di esecuzione, quando quando 'delete' viene richiamato su un oggetto Cpp, non rimarrà più nella memoria.

Durante la scrittura Cpp, abbiamo condiviso puntatore e puntatori deboli che è simile al forte e debole in Objective C.

http://philjordan.eu/article/mixing-objective-c-c++-and-objective-c++ http://www.raywenderlich.com/62989/introduction-c-ios-developers-part-1

Problemi correlati