2011-01-04 39 views
6

Tôi muốn có thể sử dụng Cmockery để giả lập các hàm C được gọi từ mã C++ mà tôi đang thử nghiệm. Là một bước về phía đó, tôi đã đổi tên ví dụ Cmockery run_tests.c để run_tests.cpp, và đang cố gắng để biên dịch và liên kết nó với cmockery.c:Làm cách nào để biên dịch và liên kết mã C++ với mã C đã biên dịch?

g++ -m32 -DHAVE_CONFIG_H -DPIC -I ../cmockery-0.1.2 -I /usr/include/malloc -c run_tests.cpp -o obj/run_tests.o 
gcc -m32 -DHAVE_CONFIG_H -DPIC -Wno-format -I ../cmockery-0.1.2 -I /usr/include/malloc -c ../cmockery-0.1.2/cmockery.c -o obj/cmockery.o 
g++ -m32 -o run_tests obj/run_tests.o obj/cmockery.o 

Hai dòng lệnh đầu tiên (để biên dịch) thành công , nhưng sau khi người cuối cùng tôi nhận được:

Undefined symbols: 
    "_run_tests(UnitTest const*, unsigned long)", referenced from: 
     _main in run_tests.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

Đó biểu tượng không xác định là từ dòng 29 của run_tests.cpp:

return run_tests(tests); 

các run_tests() chức năng được định nghĩa trong cmocker y C.

Sau khi đọc "Linking C++ code with 'gcc' (without g++)", tôi đã cố gắng:

gcc -lstdc++ -m32 -o run_tests obj/run_tests.o obj/cmockery.o 

Nhưng có kết quả tương tự:

Undefined symbols: 
    "_run_tests(UnitTest const*, unsigned long)", referenced from: 
     _main in run_tests.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

Làm thế nào để biên dịch và liên kết C++ code để nó tìm thấy những biểu tượng trong mã C?

+0

Không có câu trả lời nào (tại thời điểm viết nhận xét này) làm rõ rằng tôi không cần sửa đổi cmockery.h. Tôi có thể đặt 'extern" C "' khai báo xung quanh '#include ' trong run_tests.cpp. Tôi sẽ chấp nhận câu trả lời đầu tiên để làm rõ điều này. –

Trả lời

7

Tôi nghĩ rằng bạn có thể nhận được thinkgs để liên kết từ C++ bằng cách thêm những điều sau đây xung quanh nội dung của file cmockery.h:

Tại hoặc gần đầu:

#if defined(__cplusplus) 
extern "C" { 
#endif 

Tại hoặc gần kết thúc:

#if defined(__cplusplus) 
} 
#endif 

Bằng cách đó, sử dụng các tiêu đề trong nguồn C sẽ bỏ qua các extern "C" phần của việc kê khai, nhưng khi tiêu đề là bao gồm trong C++ được xây dựng, các trình biên dịch sẽ được thông báo đúng rằng liên kết cho các khai báo trong tiêu đề đó sử dụng ngữ nghĩa C.

Đối với một thử nghiệm nhanh-n-bẩn hoặc nếu bạn không muốn thay đổi tiêu đề, bạn có thể thử:

extern "C" { 
#include "cmockery.h" 
} 

nhưng sở thích của tôi sẽ được đặt khối extern "C" trong tiêu đề (và duy nhất xung quanh những thứ được yêu cầu - có thể cần một chút phân tích).

+0

Tại sao bạn xem xét đặt 'extern" C "' xung quanh '# include'" nhanh chóng-n-bẩn "? –

+0

Trong trường hợp chung vì nó có thể áp dụng công cụ sửa đổi 'extern" C "' thành công cụ không mong đợi nó (đặc biệt nếu tiêu đề bao gồm các tiêu đề khác là nhận thức C++). Các tiêu đề có thể xử lý điều này bằng cách sử dụng thông số khai báo 'extern" C++ "', nhưng tôi chỉ thấy được sử dụng một lần để xử lý trường hợp này (có lẽ vì nó ít được biết đến, và nó không cần thiết gần bằng 'extern" C " 'phiên bản). –

5

Trong tập tin tiêu đề của bạn bao gồm bằng C++ mã, bạn cần extern "C" tờ khai cho tất cả các chức năng được biên soạn trong C.

2

khi bạn bao gồm các tập tin tiêu đề C từ C++, bạn đã bao bọc các nguyên mẫu với extern "C" { .... }? Nếu bạn không có tên hàm C++ thì sẽ bị "xén" tại thời điểm liên kết.

2

Như Karl đã nói, extern "C" { .. } là cần thiết.

Lý do: C++ mangles tên (thêm ký tự vui) để liên kết được nhập an toàn. C không, do đó, trong ngôn ngữ đó, liên kết foo(int) đến foo(double) là có thể (nhưng sai và đáng xấu hổ).

Để có khả năng tương tác thành công, bạn cần báo cho trình biên dịch C++ biết rằng một số tên hàm không bị xáo trộn, để liên kết thành công.

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