2012-06-06 19 views
6

Estoy intentando crear una definición de macro que puede emitir C++ o Objective-C dependiendo del contexto pero no parece poder construir un NSString dentro de una macro fácilmente. La versión de C++ es simple, ya que utiliza cuerdas regulares, pero haciendo que emite NSString está demostrando ser difícil:Definición del preprocesador de Objective-C, declaración dinámica de C-String a NSString

#define FOO(x) bar(@##x) 

el resultado que se pretende es convertir una cadena de argumentos para una discusión NSString anteponiendo con @:

FOO("x") 
// => bar(@"x") 

Lo que obtengo en cambio, es un error que impide su compilación:

Pasting formed '@"x"', an invalid preprocessing token 

Respuesta

5
NSString *x = @"text"; 

Igual:

NSString *x = CFSTR("text"); 

PS NSString * y CFStringRef y __CFString * y también NSCFStringRef son todos iguales: Toll-Free Bridged Types

+0

'CFSTR' es prometedor pero es un' CFStringRef' y no un 'NSString *'. – tadman

+1

@tadman son uno y lo mismo, y están libres de puente. –

+1

@tadman: CFStringRef = NSString. – Dani

3

No puede utilizar ## para concatenar los elementos a menos que formen un procesamiento previo válida símbolo juntos, pero se puede llamada al constructor NSString 's que toma una cadena C, así:

#define FOO(x) [NSString stringWithUTF8String:(x)] 
+0

¿Va a ser algo que deba ser desasignado más tarde, a diferencia de '@" ... "' es estático, ¿verdad? – tadman

+0

@tadman Esto produce una cadena autorrellenada, no la posee a menos que la retenga. – dasblinkenlight

+0

Ah, es bueno saberlo. – tadman

3

Um, ¿por qué no esto:

#define FOO(x) bar(@x) 

?

No es necesario hacer token pegando o stringifying o algo raro. Solo quiere que lo que está en la lista de argumentos en el punto de sustitución sea precedido por un signo @. Así que haz eso.

+0

solo funciona si x está entre comillas. A veces eso no es deseable. Por ejemplo: '#define CASE_TO_NAME (x) case x: return (NSString *) CFSTR (x); break' luego una instrucción switch 'switch (val) {CASE_TO_NAME (foo); CASE_TO_NAME (barra); // etc.} ' – Olie

+0

Claro, pero de eso no se trataba la pregunta. Y su ejemplo se romperá porque no codifica 'x' en' CFSTR (x) '. –

+0

Mi ejemplo se soluciona cuando cambia a 'CFSTR (#x)', que debería ser obvio. (¿Por qué no puedo editar mi comentario ?!) – Olie

Cuestiones relacionadas