2011-08-12 30 views
7

Tôi có nhiều mã trong C++, ban đầu được xây dựng trên PC. Tôi đang cố gắng làm cho nó hoạt động với Objective-C trên máy Mac. Để kết thúc, tôi tạo ra một khung Objective-C để chứa mã C++ và thêm một wrapper mỏng. Nhưng tôi đang chạy vào một vấn đề typedef trong mã C + + của tôi.Sử dụng C++ với Objective-C, Làm cách nào để khắc phục "Khai báo xung đột" typedef int BOOL '"?

Khi tôi đang làm việc với C++ trên PC, tôi đã sử dụng biến số BOOL được xác định trong WinDef.h. Vì vậy, khi tôi di chuyển mọi thứ trên máy Mac, tôi đã thêm vào typedef int BOOL; để đảm bảo biến số BOOL vẫn sẽ biên dịch như mong đợi.

Nhưng khi tôi cố gắng biên dịch, tôi gặp lỗi: "Conflicting declaration 'typedef int BOOL'". Tôi cho rằng điều này là bởi vì BOOL là một từ khóa trong Mục tiêu-C, và do đó đã được xác định. Tôi cũng không thể chỉ sử dụng Objective-C BOOL vì nó là một unsigned char và không phải là int.

Trong khi tôi đang tìm kiếm các giải pháp có thể, tôi tìm thấy one đề cập đến undefining BOOL, nhưng tôi không thể tìm cách thực hiện điều đó (cũng không biết liệu nó có hoạt động không). Another gợi ý đổi tên BOOL trong các tệp C++ thành một thứ không phải là từ khóa. Đề xuất này không phải là một lựa chọn cho tôi vì các dự án khác dựa vào mã C++. Lý tưởng nhất, bất kỳ thay đổi nào tôi thực hiện phải ở trong một tệp hoặc ít nhất không nên tác động tiêu cực đến mã trên máy tính Windows.

Làm cách nào để xác định định nghĩa mục tiêu C của BOOL cho các tệp C++ của tôi và sử dụng định nghĩa C++ mà tôi đã thêm? Có cách nào tốt hơn để giải quyết vấn đề này không?

Trong trường hợp nó giúp Tôi đang sử dụng: Xcode 3.2.5, phiên bản 64-bit và Mac OS X 10.6.6

Thanks cho bất kỳ hướng dẫn!

+0

Tại sao bạn sử dụng 'BOOL' ngay từ đầu? C++ đã có kiểu 'bool'. –

+1

Bởi vì trên Windows, nhiều API sử dụng kiểu BOOL, được định nghĩa bởi Windows, mà thực sự là một int. Nó không tương thích với BOOL, đặc biệt là nếu nó không phải là một phần của cấu trúc phải được chuyển tới một API như vậy (Trên Windows, bool có kích thước byte và BOOL là bốn byte). –

Trả lời

5

Tôi là một chút bối rối bởi một số các cuộc thảo luận, nhưng thay vì typedef int BOOL; thế nào về chỉ:

#ifndef BOOL 
    #define BOOL int 
#endif 

Nếu bạn đang sử dụng typedef sau đó #undef sẽ không làm việc kể từ khi họ là hai việc khác nhau. #define/#undef hoạt động trên các ký hiệu tiền xử lý thực hiện thay thế, trong khi typedef là một phần của ngôn ngữ tạo bí danh loại khác.

Biểu tượng tiền xử lý có thể không xác định tại bất kỳ điểm nào vì nó chỉ đơn giản là một hướng dẫn cho bộ tiền xử lý yêu cầu nó không còn sử dụng định nghĩa đó khi thực hiện thay thế. Tuy nhiên, không thể không xác định được typedef vì nó là thứ được tạo trong phạm vi cụ thể, thay vì xử lý tuyến tính xảy ra bằng bộ xử lý trước. (Trong cùng một cách, bạn sẽ không mong đợi để có thể tuyên bố một biến toàn cầu int x; và sau đó tại một số điểm trong mã của bạn có thể nói 'ngừng nhận ra x là một biến.')

Lý do tôi đề xuất #define trong câu trả lời của tôi là có thể rằng ObjectiveC #define chỉ được nhấn khi biên dịch một số mã của bạn. Đó có thể là giải thích tại sao bạn có thể gặp lỗi trong C++ khi bạn xóa typedef nhưng vẫn nhận được xung đột nếu nó ở đó. Tuy nhiên, nếu giả định là chính xác, khi bạn kiểm tra định nghĩa trước khi thử để xác định nó, bạn sẽ có thể tránh được các định nghĩa xung đột khi chúng xảy ra.

Lưu ý cuối cùng: trong trường hợp cụ thể này, bạn cũng có thể chỉ cần đặt typedef bên trong séc thay vì #define. Tuy nhiên, tôi bị cuốn hút theo cách tôi đã làm cả hai vì nó là một thành ngữ rất phổ biến, và bởi vì khối đó cũng sẽ ngăn bạn định nghĩa nó hai lần trong mã C++ của bạn nếu nó kết thúc bao gồm hai lần. Có lẽ không phải là lý do rất hấp dẫn nếu bạn rất thích số typedef và biết đó không phải là vấn đề trong mã. :)

+0

:) oops, tôi cũng đăng sau khi vấn đề của bạn đã được giải quyết, vui mừng bạn đã nhận nó làm việc! – shelleybutterfly

+0

Tôi đã thử cả hai cách bạn đã đề cập ('# ifdef' với' #define BOOL int' và 'typedef int BOOL;' bên trong). Cách đầu tiên làm việc tốt, nhưng thứ hai tạo ra cùng một lỗi 'Khai báo xung đột '(tôi hoàn toàn không hiểu làm thế nào có thể, chỉ cần lặp lại những gì Xcode nói với tôi!). Cảm ơn các giải pháp thay thế! –

+0

huh, rất kỳ quặc. à, có lẽ là một trong những điều tốt nhất không nên nghĩ quá nhiều về nó. : D và cảm ơn ghi chú! ♡ – shelleybutterfly

0

AFAIK, BOOL cũng là #define trong Mục tiêu-C. Bạn sẽ có vấn đề với bạn mâu thuẫn BOOL xác định, ngay cả khi bạn quản lý để

#undef BOOL 

vì loại của bạn và loại của nó không nhất thiết phải phù hợp với kích thước và "signedness". Phải BOOL của bạn thực sự là một int, thay vì bất cứ điều gì nó là Obj-C định nghĩa nó như là? Nói cách khác, bạn không thể bỏ qua #define và chỉ cần sử dụng Obj-C?

+0

Nếu tôi nhận xét ra 'typedef int BOOL' trong tệp C++ của tôi, tôi nhận được lỗi trong suốt phần còn lại của các tệp C++ bất cứ lúc nào' BOOL' được sử dụng. Vì vậy, tôi không nghĩ rằng tôi có thể sử dụng định nghĩa BOJ-C BOOL thay thế. –

+0

Làm cách nào có thể? Tôi hy vọng nó chỉ được xác định một lần. Chỉ cần loại bỏ điều đó và bao gồm "objc.h" thay thế. FWIW, loại lỗi nào? –

+1

Ồ, tôi nghĩ điều đó đã hiệu quả! Ít nhất nó biên dịch lỗi miễn phí ngay bây giờ. Tôi đã làm những gì bạn nói và thêm vào '#include ' để những điều hy vọng sẽ không còn ở đây nữa. Cảm ơn bạn! FWIW chúng hầu hết là các lỗi như ''BOOL' không đặt tên là loại' và' ISO C++ cấm tuyên bố 'BOOL' không có loại'. –

0

Nếu bạn có thể quay ngược thời gian, tôi sẽ nói "Không sử dụng typedef int BOOL trong mã của riêng bạn".

Bây giờ bạn đã thực sự thực hiện nó, mặc dù, bạn đang ở trong một chút của dưa chua. Nói chung, bạn nên tránh sử dụng các kiểu dữ liệu ngoài cho mã của riêng bạn ngoại trừ giao diện với mã bên ngoài. Các loại tiêu chuẩn là tốt, giả sử rằng bạn có thể đảm bảo biên dịch bằng trình biên dịch tuân thủ chuẩn trên mọi nền tảng bạn nhắm mục tiêu.

Giải pháp tìm kiếm thuận lợi nhất là ngừng sử dụng BOOL làm loại mã không phụ thuộc vào nền tảng của bạn. Trong thời gian chờ đợi, bạn có thể sử dụng tất cả các loại tấn công tiền xử lý để sử dụng biên dịch BOOL, nhưng bạn có thể gặp phải một số lỗi liên kết lạ nếu bạn không sử dụng BOOL theo cùng một cách (thông qua #includes) ở mọi nơi.

0

tôi sử dụng cmake để tải thư viện FreeImage và tôi đang sử dụng Kubuntu 14.x Tôi có vấn đề này với

"error: conflicting declaration ‘typedef CARD8 BOOL’" 

và tôi nghĩ rằng nó sẽ là tốt để chia sẻ giải pháp của tôi với những người mà có điều này vấn đề!

cài đặt FreeImage trên Linux:

sudo apt-get install libfreeimage-dev 

Trong file CMakeLists.txt của tôi, tôi có:

set(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY /usr/libs) 
find_path(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY, FreeImage.h) 
find_library(FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY, freeimage) 
include_directories(${FREEIMAGE_LIBRARY_AND_HEADER_DIRRECTORY}) 
target_link_libraries(freeimage) 

Và trong main.cpp của tôi, tôi có:

#include <FreeImage.h> 
#ifndef CARD8 
#define BYTE CARD8 
#define BOOL CARD8 
#endif 

Và một số mã phụ để chụp khung OpenGl trên đĩa:

void generateImage(){ 
    int w, h; // get the width and height of the OpenGL window! 
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 
    GLubyte * pixels = new GLubyte[3*w*h]; 
    glReadPixels(0,0,w,h,GL_RGB,GL_UNSIGNED_BYTE, pixels); 

    FIBITMAP * image = FreeImage_ConvertFromRawBits(pixels,w,h,3 * w, 24, 0x0000FF, 0xFF0000, 0x00FF00, false); 
    FreeImage_Save(FIF_BMP,image, "../img/text.bmp",0); 

    //Free resource 
    FreeImage_Unload(image); 
    delete[] pixels; 
} 

Tôi hy vọng điều này sẽ giúp những người có vấn đề với điều này!

Kính trọng Kahin

Các vấn đề liên quan