2012-06-06 7 views
6

Próbuję utworzyć definicję makra, która może emitować C++ lub Objective-C w zależności od kontekstu, ale nie może łatwo zbudować NSString wewnątrz makra. wersja C++ jest prosta, ponieważ używa regularnych ciągów, ale co jeden, który emituje NSString jest udowodnienie trudne:Definicja preprocesora Objective, Dynamic C-String na NSString Declaration

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

Zamierzony rezultat jest konwersja argument ciąg do argumentu NSString poprzedzając z @:

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

Co dostanę w zamian jest błąd, który uniemożliwia kompilacji:

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

Odpowiedz

5
NSString *x = @"text"; 

wynosi:

NSString *x = CFSTR("text"); 

PS NSString * i CFStringRef i __CFString * a także NSCFStringRef są takie same: Toll-Free Bridged Types

+0

'CFSTR' jest obiecujący, ale jest' CFStringRef', a nie 'NSString *'. – tadman

+1

@tadman są jednym i tym samym, i są wolne od opłat mostowych. –

+1

@tadman: CFStringRef = NSString. – Dani

3

Nie można używać ## do łączenia elementów, chyba że stanowią one ważny wstępne przetwarzanie tokena razem, ale można wywołać konstruktora NSString „s, która pobiera ciąg C, tak:

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

Czy to będzie coś, co musi zostać później anulowane, w przeciwieństwie do '@" ... " statyczne, prawda? – tadman

+0

@tadman W ten sposób powstaje autoodtwarzany ciąg znaków, którego nie masz, dopóki go nie zachowasz. – dasblinkenlight

+0

Ach, dobrze wiedzieć. – tadman

3

Um, dlaczego nie jest to:

#define FOO(x) bar(@x) 

?

Nie ma potrzeby robienia wklejek tokenów, obcinania ani niczego dziwnego. Po prostu chcesz, aby to, co znajduje się na liście argumentów w punkcie podstawienia, zostało poprzedzone znakiem @. Po prostu zrób to.

+0

działa tylko wtedy, gdy x jest w cudzysłowach. Czasami nie jest to pożądane. Na przykład: '#define CASE_TO_NAME (x) case x: return (NSString *) CFSTR (x); break', a następnie instrukcja switch 'switch (val) {CASE_TO_NAME (foo); CASE_TO_NAME (bar); // itd.} ' – Olie

+0

Oczywiście, ale nie o to chodziło. A twój przykład się zepsuje, ponieważ nie ma łańcuchów 'x' w' CFSTR (x) '. –

+0

Mój przykład jest poprawiony po zmianie na 'CFSTR (#x)', co powinno być oczywiste. (Dlaczego nie mogę edytować mojego komentarza ?!) – Olie

Powiązane problemy