23

Tôi có một macro tiền xử lý theo quy định tại build thiết lậpgiá trị macro Preprocessor để Objective-C chuỗi chữ

FOO=BAR 

Giá trị đó tôi muốn xoa bóp vào một chuỗi Objective-C đen có thể được truyền đến một phương pháp. CáC#define sau không làm việc, nhưng nó phải chứng minh những gì tôi đang cố gắng để đạt được:

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

myMethodThatTakesAnNSString(FOOLITERAL); 

Tôi hy vọng rằng tôi chỉ thiếu rõ ràng bằng cách nào đó, nhưng tôi dường như không thể tìm ra Preprocessor voodoo quyền có được những gì Tôi cần.

Trả lời

32

Sử dụng các nhà điều hành stringizing# để thực hiện một chuỗi C ra khỏi biểu tượng. Tuy nhiên, do một điều không minh bạch của tiền xử lý, bạn cần phải sử dụng hai lớp thêm macro:

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

Lý do cho sự lớp bổ sung là các nhà điều hành stringizing chỉ có thể được sử dụng trên các đối số của vĩ mô, không trên các thẻ khác. Thứ hai, nếu một đối số của macro có toán tử xâu chuỗi được áp dụng cho nó trong phần thân macro, thì đối số đó là không phải là được mở rộng dưới dạng macro khác. Vì vậy, để đảm bảo rằng FOO được mở rộng, chúng tôi gói trong macro khác, để khi STRINGIZE2 được mở rộng, nó cũng mở rộng FOO vì toán tử xâu chuỗi không xuất hiện trong phần thân của macro đó.

+0

Điều đó đã làm được. Tôi đã thử nghiệm đôi, nhưng cũng có "@" như một giá trị vĩ mô và điều đó dường như gây nhầm lẫn nó. Một khác biệt nhỏ là dòng đầu tiên không đại diện cho trường hợp của tôi ở chỗ nó không lấy thiết xây dựng #define FOOVAL FOO #define STRINGIZE (x) #x #define STRINGIZE2 (x) STRINGIZE (x) #define FOOLITERAL @ STRINGIZE2 (FOOVAL) là những gì thực sự hiệu quả đối với tôi. Nhưng câu trả lời của bạn đã cho tôi ở đó. – vagrant

+0

Xin chào @vagrant. Liệu giải pháp này vẫn làm việc cho bạn với LLVM? Tôi đang cố gắng để có được điều này để làm việc, nhưng giá trị thực tế của FOO như được định nghĩa trong các thiết lập xây dựng của tôi tiền xử lý macro không bao giờ xuất hiện. Bạn có thể cập nhật câu hỏi của mình với giải pháp phù hợp với bạn không?Chúc mừng. – epologee

+1

Tại sao không chỉ '#define Helper (STR) @ # STR'? – tadeuzagallo

-1

Lỗi nào bạn thấy chính xác? Đây là loại điều không làm việc như bạn mong đợi:

#define kMyString @"MyString" 

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

Giá trị thực tế của chuỗi cần thiết là giá trị của các vĩ mô tiền xử lý. Vì vậy, tôi không thể chỉ đặt giá trị vào mã như trong ví dụ của bạn, nó phải đến từ biến FOO. – vagrant

26

Dưới đây là một phiên bản sửa đổi của câu trả lời Adam Rosenfield với ngữ nghĩa rõ ràng hơn:

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

tôi sử dụng nó để thay thế mã như thế này:

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

với điều này:

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

case_for_type(OneEnumValue); 
case_for_type(AnotherEnumValue); 
1

Bạn cần xác định macro tiền xử lý như,

FOO=\@\"BAR\" 

Và sử dụng mã phía như,

[NSString stringWithFormat:@"macro: %@", FOO]; 
Các vấn đề liên quan