2009-08-05 37 views
8

Tôi đang viết một ứng dụng đồ họa sử dụng Objective-C cho giao diện người dùng và C++ để xử lý đồ họa và giao tiếp mạng. Tôi đọc xung quanh trên trang web của Apple đang tìm kiếm một cách để liên kết hoặc là .dylib hoặc .so với mã C++ của tôi trong đó cho dự án Xcode của tôi, nhưng dường như không có gì hoạt động. Tôi đã có thể nhận được dự án để tham khảo nó và liên kết với nó, nhưng khi tôi cố gắng gọi các chức năng từ đó .dylib, nó đã nói rằng nó không biết những gì tôi đã cố gắng để làm. Có ai biết chuyện gì đang diễn ra ở đây không?liên kết và sử dụng thư viện C++ với ứng dụng Objective-C

Tôi biết rằng Objective-C có tất cả các thư viện tôi cần làm đồ họa và kết nối mạng, nhưng tôi chỉ cảm thấy thích làm như thế này. Tôi đã không làm nhiều C++ trong một thời gian và tôi muốn tìm hiểu thêm Objective-C, vì vậy cách tốt hơn để sử dụng chúng với nhau?

Cảm ơn, Robbie

Trả lời

13

Bạn đang đi để đạt một trở ngại trong các hình thức của những gì được gọi là "tên mangling". C++ lưu trữ tên hàm theo cách không tương thích với Obj-C.

Mục tiêu-C không triển khai các lớp theo cùng cách với C++, do đó, nó sẽ không thích nó.

Một cách xung quanh việc này là triển khai một tập hợp các hàm C đơn giản gọi hàm C++. Sẽ là một thách thức tốt để giữ số lượng hàm C thấp nhất có thể! Bạn sẽ kết thúc với một giao diện nhỏ gọn đẹp! :)

Kê khai các chức năng này trong một tập tin ++ C, bạn sẽ cần phải đánh dấu chúng là C với:

extern "C" int function_name(char *blob,int number, double foo) {...} 

này vô hiệu hóa các tiêu chuẩn tên mangling.

Tạo tệp tiêu đề có các nguyên mẫu cho tất cả các chức năng này mà bạn có thể chia sẻ với mã C mục tiêu của mình.

Bạn sẽ không thể vượt qua các lớp học theo cùng một cách (vì mã ObjC của bạn không thể sử dụng chúng), nhưng bạn sẽ có thể chuyển con trỏ (mặc dù bạn có thể phải nói dối về các loại ít).

+6

Một tùy chọn khác là tạo tệp mục tiêu-C++ của bạn đối tượng-C++ bằng cách thay đổi phần mở rộng của chúng thành .mm và sau đó bạn có thể trộn mã C++ và Objective-C của bạn. – Amok

+0

Điều này làm việc cho tôi. Tôi đã tạo một lớp trong một tệp '.mm' và có thể liên kết với các thư viện C++ một cách hoàn hảo và gọi các phương thức trình bao bọc từ các tệp .'m' của tôi. Cảm ơn! –

13

Hầu hết các dự án tôi làm việc đều có giao diện người dùng ObjC và phần phụ trợ C++. Nếu bạn đang xử lý độc quyền với các hàm, thì sửa lỗi mang tên Dave Gamble là chính xác, nhưng nếu bạn đang xử lý các tình huống phức tạp hơn, nơi bạn cần xử lý cả hai đối tượng ObjC và C++, thì tốt nhất là đặt các đối tượng C++ trong các đối tượng ObjC. Sử dụng các tham chiếu mờ (là một cách rất lạ mắt để nói là void*), bạn có thể thực sự trao đổi các đối tượng C++ trong ObjC và ngược lại. Tôi có một số sample code có thể hữu ích.

Điều đó nói rằng, đối với đồ họa, bạn có thể sẽ thực hiện một hit hiệu suất nghiêm trọng làm tùy chỉnh C++ thay vì sử dụng Core Image và các khuôn khổ liên quan. Core Image và các khung công tác đồ họa khác được tối ưu hóa cao cho Mac, và bạn không thể làm tốt hơn với C++ được cuộn bằng tay (hoặc thậm chí là C++ được viết rất tốt mà không dành riêng cho Mac). Khi bạn di chuyển đến 10.6 và công văn trung tâm lớn, sự khác biệt hiệu suất sẽ càng đáng chú ý hơn bởi vì bạn sẽ mất tất cả các tiến bộ song song mà bạn sẽ nhận được miễn phí nếu không. Điều này không liên quan gì đến ObjC; Core Image là C. Bạn có thể gọi nó từ C++ tất cả những gì bạn thích. Tôi chỉ khuyên bạn không nên xử lý đồ họa tùy chỉnh trên Mac bằng bất kỳ ngôn ngữ nào trừ khi bạn cần tính di động hoặc bạn có chuyên môn cần thiết để đánh bại Core Image.

+0

Xin chào, Trong ví dụ được trình bày như tôi có thể thấy bạn đang gói một đối tượng C++ vào Objective-C++ (phần mở rộng tệp .mm) và không vào Objective-C (phần mở rộng tệp .m). Theo tôi hiểu bạn không thể có đối tượng Objective-C ** A ** sử dụng đối tượng Objective-C++ bao bọc ** B **. Bạn phải thay đổi phần mở rộng của mọi tập tin '.m' thành' .mm'. Vì vậy, bạn phải làm cho dự án của bạn Mục tiêu-C++! – MichK

+2

Điều đó không đúng. Miễn là 'B.h' là ObjC thuần túy (khai báo không có C++), bạn hoàn toàn có thể gọi' B' từ 'A'. Bạn hoàn toàn không phải thay đổi mọi '.m' thành' .mm' (và không nên). –

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