2013-04-24 27 views
5

Tôi đang phát triển mã cho một hệ thống nhúng (cụ thể là PSoC 5, sử dụng Trình tạo PSoC) và viết bằng C++.Tại sao Vtables không được triển khai đúng trên nền tảng nhúng?

Mặc dù tôi đã vượt qua hầu hết các rào cản với việc sử dụng C++, trước tiên hãy biên dịch bằng C++ bằng cờ biên dịch -x c++, xác định toán tử mới và xóa, đảm bảo ngoại lệ không được ném cờ biên dịch -fno-exception. vào một bức tường gạch khi nói đến việc sử dụng các chức năng ảo.

Nếu tôi thử và khai báo hàm ảo, trình biên dịch sẽ cho tôi lỗi undefined reference to "vtable for __cxxabiv1::__class_type_info". Cách duy nhất để giải quyết vấn đề này là sử dụng cờ biên dịch -fno-rtti để ngăn lỗi và làm cho nó biên dịch thành công. Tuy nhiên, nếu tôi làm điều đó, chương trình nhúng bị treo khi cố gắng chạy hàm ảo bị quá tải, và tôi nghĩ điều này là do vtable không tồn tại.

Tôi không thấy lý do tại sao bạn không thể triển khai vtables trên nền tảng được nhúng, vì tất cả là không gian thừa trong bộ nhớ trước hoặc sau đối tượng thành viên (tùy thuộc vào trình biên dịch chính xác).

Lý do tôi đang cố gắng sử dụng các chức năng ảo là vì tôi muốn sử dụng FreeRTOS với C++ và những người khác đã thực hiện điều này bằng cách sử dụng các chức năng ảo (xem http://www.freertos.org/FreeRTOS_Support_Forum_Archive/July_2010/freertos_Is_it_possible_create_freertos_task_in_c_3778071.html để thảo luận, và https://github.com/yuriykulikov/Event-driven_Framework_for_Embedded_Systems). khung công tác)

+0

Bạn liên kết thư viện thực thi/chia sẻ của mình như thế nào? – jxh

+2

Bạn có chắc chắn điều này là do thực tế là bạn biên dịch cho một nền tảng nhúng? Bạn đã thử biên dịch các phần liên quan của mã trên nền tảng chuẩn chưa? – jogojapan

+0

IDE PSoC chạy tập lệnh trình liên kết như là một phần của quá trình xây dựng. Tôi đã bao gồm cờ '-lstdC++' để đảm bảo nó gắn kết với thư viện chuẩn C++. – gbmhunter

Trả lời

5

Thực tế là thông báo lỗi đề cập đến một lớp có tên __cxxabiv1 cho thấy rằng bạn không liên kết với đúng thời gian chạy C++ cho nền tảng của bạn. Tôi không biết gì về PSoC, nhưng trên nhiều nền tảng "bình thường", loại lỗi này có thể xảy ra nếu bạn sử dụng lệnh gcc (resp. clang) tại thời gian liên kết thay vì g++ (resp. clang++); hoặc trong trường hợp handwavey nếu bạn sử dụng -lc++ mà không cần -stdlib=libc++ hoặc -lstdc++ mà không cần -stdlib=libstdc++.

Sử dụng tùy chọn -v để kiểm tra dòng lệnh trình liên kết của bạn và cố gắng tìm chính xác thư viện thời gian chạy C++ nào đang được kéo. Nó có thể được đặt tên là libcxxabi hoặc libcxxrt.

This guy here cung cấp hướng dẫn từng bước để biên dịch C++ trong Trình tạo PSoC; nhưng anh ta không bao giờ tìm ra cách liên kết với thư viện thời gian chạy C++, vì vậy tất cả các mẹo của anh ấy đều tập trung vào cách xóa C++ isms khỏi mã của bạn (-fno-rtti, -fno-exceptions, ...). Tôi đồng ý rằng dường như không có bất kỳ thông tin trực tuyến nào về cách thực sự sử dụng C++ bằng PSoC.

Đối cụ lỗi này, bạn có thể luôn luôn cố gắng xác định biểu tượng thiếu tự hỏi:

// file "fix-link-errors.cpp" 
namespace __cxxabiv1 { 
    class __class_type_info { 
     virtual void dummy(); 
    }; 
    void __class_type_info::dummy() { } // causes the vtable to get created here 
}; 

Hoặc nhiều linkers có khả năng xác định những biểu tượng không xác định như 0x0 qua các tùy chọn dòng lệnh như -C hoặc --defsym . Tuy nhiên, đó không chỉ là một ý tưởng tồi mà còn bất tiện, bởi vì bạn phải tìm ra tên thực tế (bị xâu) của đối tượng vtable là gì, và mối liên kết không cho bạn biết điều đó. (Đây là GCC, nó có thể là một cái gì đó giống như __ZTVN10__cxxabiv117__class_type_infoE.)

Một trong những "giải pháp" đó sẽ dẫn đến các sự cố khủng khiếp nếu chương trình đã từng cố gắng làm bất kỳ điều gì có vtable; nhưng họ sẽ đóng liên kết, nếu đó là tất cả những gì bạn quan tâm và bạn biết chương trình sẽ không bao giờ thực sự sử dụng RTTI. Nhưng trong trường hợp đó, nó sẽ là đủ để sử dụng -fno-rtti một cách nhất quán trên toàn bộ dự án của bạn.

Điều gì, cụ thể, đã xảy ra khi bạn sử dụng -fno-rtti?

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