23

Mam makra preprocesora zdefiniowany w ustawieniach kompilacjiPreprocessor makro wartość do Objective-C ciąg dosłownym

FOO=BAR 

To wartość Chcę wmasować ciąg Objective-C dosłownym, które mogą być przekazywane do metody. Poniższy #define nie działa, ale powinna ona wykazać, co usiłuję osiągnąć:

#define FOOLITERAL @"FOO" //want FOOLITERAL to have the value of @"BAR" 

myMethodThatTakesAnNSString(FOOLITERAL); 

Spodziewam się, że jestem po prostu brakuje oczywiste jakoś, ale nie wydaje się znaleźć właściwą preprocesora voodoo, aby dostać to, co Potrzebuję.

Odpowiedz

32

użyć operatora stringizing# aby ciąg C z symbolem. Jednakże, ze względu na dziwactwo preprocesora, trzeba użyć dwóch dodatkowych warstw makr:

#define FOO BAR 
#define STRINGIZE(x) #x 
#define STRINGIZE2(x) STRINGIZE(x) 
#define FOOLITERAL @ STRINGIZE2(FOO) 
// FOOLITERAL now expands to @"BAR" 

Powodem dodatkowych warstw jest to, że operator stringizing mogą być wykorzystywane wyłącznie na argumenty makra, nie na innych tokenach. Po drugie, jeśli argument makra ma operator łańcuchowania zastosowany do niego w treści makra, argument ten jest , a nie rozwinięty jako inne makro. Tak więc, aby upewnić się, że FOO zostanie rozwinięty, zawijamy kolejne makro, aby po rozwinięciu się STRINGIZE2 rozwinął się także FOO, ponieważ operator naciągania nie pojawia się w ciele tego makra.

+0

To się udało. Próbowałem podwójnego pośrednictwa, ale również "@" jako wartość makro i wydaje się, że to zmyli. Jedna mała różnica polega na tym, że pierwsza linia nie reprezentuje moim przypadku w tym, że nie pobiera kompilacji ustawienie #define FOOVAL FOO #define STRINGIZE (x) #x #define STRINGIZE2 (x) STRINGIZE (x) #define FOOLITERAL @ STRINGIZE2 (FOOVAL) jest to, co faktycznie działa dla mnie. Ale twoja odpowiedź mnie tam dopadła. – vagrant

+0

Witam @vagrant. Czy to rozwiązanie nadal działa z LLVM? Próbuję uruchomić to, ale rzeczywista wartość FOO zdefiniowana w makrach preprocesora moich ustawień kompilacji nigdy się nie wyświetla. Czy mógłbyś zaktualizować swoje pytanie za pomocą rozwiązania, które działa dla Ciebie?Twoje zdrowie. – epologee

+1

Dlaczego po prostu '#define Helper (STR) @ # STR'? – tadeuzagallo

-1

Jaki błąd widzisz dokładnie? Tego typu rzeczy nie działa zgodnie z oczekiwaniami:

#define kMyString @"MyString" 

[NSString stringWithFormat:@"macro: %@", kMyString]; 
+3

Rzeczywista wartość ciągu konieczna jest wartość makra preprocesora. Więc nie mogę po prostu wstawić wartości do kodu, jak w twoim przykładzie, musi pochodzić ze zmiennej FOO. – vagrant

26

Oto zmodyfikowana wersja odpowiedź Adama Rosenfield jest z jaśniejszych semantyki:

#define NSStringize_helper(x) #x 
#define NSStringize(x) @NSStringize_helper(x) 

Używam go zastąpić kod tak:

case OneEnumValue: name = @"OneEnumValue"; break; 
case AnotherEnumValue: name = @"AnotherEnumValue"; break; 

z tym:

#define case_for_type(type) case type: name = NSStringize(type); break 

case_for_type(OneEnumValue); 
case_for_type(AnotherEnumValue); 
1

You trzeba zdefiniować makro preprocesora, takie jak,

FOO=\@\"BAR\" 

i użyć kodu jak strona,

[NSString stringWithFormat:@"macro: %@", FOO];