2011-12-06 28 views
6

Tôi thích chức năng liên kết của GNU để bao bọc các chức năng rất nhiều. Tôi thường sử dụng mô hình đó, ví dụ: các hàm gọi không xác định như rand(). Hãy xem xét ví dụ sau đây mà tôi muốn viết một bài kiểm tra đơn vị cho giveMeANumber:Đóng gói các hàm C++ với trình liên kết GNU

//number.cpp 
int giveMeANumber() { 
    return rand() % 6 + 1; 
} 

tôi có thể quấn gọi rand với GNU quấn chức năng liên kết như thế này:

//test.cpp 
extern "C" int __wrap_rand(void) { 
return 4; 
} 

void unitTest() { 
    assert giveMeANumber() == 5; 
} 

$ g++ test.cpp -o test number.o -Xlinker --wrap=rand 

Có cách nào để làm tương tự với các hàm C++ bình thường? Sau đây không làm việc, tôi đoán đó là vì mangling tên. Nhưng ngay cả khi tôi thử nó với tên bị xé nó không hoạt động.

//number.cpp 
int foo() { 
    //some complex calculations I would like to mock 
} 
int giveMeANumber() { 
    return foo() % 6 + 1; 
} 

//test.cpp 
extern "C" int __wrap_foo(void) { 
return 4; 
} 

$ g++ test.cpp -o test number.o -Xlinker --wrap=foo 

Bất kỳ ý tưởng nào?

+0

Thực ra, rand là hàm xác định. Nó trả về một chuỗi số giả ngẫu nhiên. Các cuộc gọi rand sẽ trả về cùng một chuỗi các số cho bất kỳ hạt giống nào được sử dụng với srand. – TJD

+1

Được rồi, bravo, đó là sự thật. Nhưng để giữ ví dụ ngắn và dễ đọc, tôi không sử dụng hạt giống. – Mike

+0

Bạn cần đổi tên '__wrap_foo' thành' getRandomNumber'. (http://xkcd.com/221/) –

Trả lời

8

Bạn cần phải hoặc cũng extern "C" chức năng bạn muốn quấn (nếu có thể) hoặc bạn cần phải quấn cái tên đọc sai, ví dụ, __wrap__Z3foov và sau đó vượt qua --wrap=_Z3foov để mối liên kết.

Lấy dấu gạch dưới bên phải là một chút khó khăn. Điều này phù hợp với tôi:

$ cat x.cc 
#include <iostream> 
using namespace std; 

int giveMeANumber(); 

int main() { 
    cerr << giveMeANumber() << endl; 
    return 0; 
} 

$ cat y.cc 
int giveMeANumber() { 
    return 0; 
} 

extern "C" int __wrap__Z13giveMeANumberv() { 
    return 10; 
} 

$ g++ -c x.cc y.cc && g++ x.o y.o -Wl,--wrap=_Z13giveMeANumberv && ./a.out 
10 
+0

Liên kết C cho hàm C++ được bao bọc không phải là một tùy chọn vì hàm này có thể bị quá tải và vẫn có thể gọi nó từ các hàm C++ khác. Tôi đã cố gắng bọc tên bị xé, nhưng nó không hoạt động. Những gì tôi đã làm là: 'extern" C "int __wrap__Z3foov (void) { \t return 4; } void thisIsATest() { khẳng định 5 == giveMeANumber(); } 'cùng với tùy chọn trình liên kết' -Xlinker --wrap = _Z3foov'. Thật không may, hàm 'foo' thực vẫn được gọi. Bất kỳ ý tưởng? – Mike

+0

Tôi đã thêm một ví dụ. Đã cho tôi một thời gian để có được tất cả các underscores ngay. – smparkes

+0

Và cảm ơn câu hỏi. Tôi thậm chí còn không biết về -. Rất đẹp. – smparkes

1

Dường như bạn đang cố gắng thử các chức năng và lớp học để kiểm tra. bạn đã xem xét sử dụng Google Mock

+1

Sử dụng Google mô phỏng không phải là một lựa chọn cho tôi. Tôi muốn thực hiện điều này chỉ với sự trợ giúp của trình liên kết GNU. – Mike

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