2010-04-26 17 views
40

Estoy intentando mezclar Objective-C con C++. Cuando compilo el código, recibo varios errores.Mezcla de Objective-C y 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++"; 
    } 

}; 

Éstos son los errores:

/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

No se olvide que obligar a los usuarios de su clase a ObjC use ObjC++ si coloca C++ en el encabezado; use punteros opacos para evitar eso. –

+0

@gf Entonces, ¿cómo recomendarías hacer esto entonces? ¿Debería usar un puntero de vacío, o puedo usar un tipo de identificación? – LandonSchropp

+1

Para evitar perder seguridad tipo yo personalmente prefiero las estructuras declaradas (http://stackoverflow.com/questions/2262011/adding-c-object-to-objective-c-class/2262395) pero también he visto * "privado" * Clases ObjC (es decir, a través de variables de instancia 'id'). –

Respuesta

73

Debe nombrar sus archivos .m.mm. Y podrá compilar código C++ con Objective-C.

Así que, siguiendo su ejemplo, su archivo AView.m debe ser nombrado AView.mm. Es simple como eso. Funciona muy bien. Utilizo muchos contenedores std (std :: vector, std :: queue, etc.) y código C++ heredado en proyectos de iPhone sin complicaciones.

+0

Lo que no puedo cambiar el nombre del archivo .m a .mm debido a otras clases que reportarán un error si uso la extensión .mm. ¿Alguna otra solución es la mente? – Scar

5

No importa, me siento estúpido. Todo lo que tiene que hacer es cambiar el nombre de AView.m a AView.mm para que el compilador sepa que es Objective-C++, y se compila sin problemas.

+2

¡Me alegro de que sea así de simple, ya que ahora puedo usar SU código como plantilla para probar esta mierda yo mismo! – Teekin

+1

Hay otra forma de hacerlo: en la ventana de atributos de archivo (olvídate de cómo se llama), la ventana de la derecha cuando se hace clic en un archivo en Navigator) puedes establecer el tipo de archivo independientemente de su extensión de archivo. –

2

se podía mantener más limpia la interfaz con la declaración de avance de las clases C++:

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

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

Esto no responde la pregunta. Se trata de un estilo de código y no tiene nada que ver con los errores del compilador informados en la pregunta. Debería haber sido un comentario. –

0

En situaciones en las que desea introducir una simple función de C++ como std::cout << lame luego caliente ofrece una buena alternativa.

cambiar el "Identity and Type" De: Objective-C source Para: Objective-C++ source

La extensión .mm simplemente identifica el tipo de archivo; y luego busca un Objective-C++ no un tipo Objective-C.

1

Estoy compartiendo algunos de los puntos que he entendido sobre este tema.

Podemos mezclar archivos .cpp y .m con una interfaz C pura. Como sabemos, el compilador de Clang admitirá C++, Objective C y Objective C++, podría ser un mejor método para mezclar estos lenguajes.

Una cosa al momento de mezclar estos lenguajes es tener cuidado con los archivos de encabezado. Podemos mantener el C++ fuera de nuestros encabezados de Objective C al declarar los objetos Cpp en extensiones de clase.

Como alternativa, podemos declarar los objetos cpp justo al comienzo del bloque @implementation en nuestro archivo Objective Cpp (.mm).

La gestión de la memoria será una preocupación cuando se trata de objetos Cpp. Podemos asignar memoria a un objeto usando 'nuevo' y liberar la memoria llamando 'eliminar objeto'. Normalmente, si estamos usando ARC, no necesitamos estar conscientes de liberar la memoria de un objeto.

Al utilizar las clases cpp, podemos declarar un objeto Cpp de dos maneras, por ejemplo CppWrapper wrapper y CppWrapper * wrapper donde CppWrapper es una clase Cpp. Cuando estamos usando lo último, el programador es responsable de administrar la memoria.

Otra cosa importante es que cuando llamamos a un método C objetivo con parámetros, estamos pasando las referencias, mientras que en cpp necesitamos pasar los parámetros por referencia usando la palabra clave '&', de lo contrario copia del objeto ha sido aprobado.

La desasignación del objeto Objective C se maneja en tiempo de ejecución, donde cuando se invoca 'delete' a un objeto Cpp, ya no quedará en la memoria.

Al escribir Cpp, hemos compartido puntero y punteros débiles que es similar a los fuertes y débiles en Objective C.

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