2011-12-06 18 views
6

के साथ लपेटना सी ++ फ़ंक्शंस मुझे कार्यों को लपेटने के लिए जीएनयू लिंकर कार्यक्षमता पसंद है। मैं आमतौर पर इसे नकली उदाहरण का उपयोग करता हूं nondeterministic समारोह रैंड() की तरह कहते हैं। निम्नलिखित उदाहरण पर विचार जहाँ मैं giveMeANumber के लिए एक इकाई परीक्षण लिखने के लिए करना चाहते हैं:जीएनयू लिंकर

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

मैं इस तरह जीएनयू लिंकर कार्यप्रणाली चादर के साथ रैंड करने के लिए कॉल लपेट कर सकते हैं:

//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 

वहाँ कोई तरीका है सामान्य सी ++ कार्यों के साथ ऐसा करने के लिए? निम्नलिखित काम नहीं करता है, मुझे लगता है कि यह नाम उलझन की वजह से है। लेकिन जब भी मैं उलझन वाले नाम से कोशिश करता हूं तो यह काम नहीं करता है।

//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 

कोई विचार?

+0

वास्तव में, रैंड एक निर्धारक कार्य है। यह एक छद्म यादृच्छिक संख्या अनुक्रम देता है। रैंड कहते हैं कि रैंड एसआरएंड के साथ इस्तेमाल किए गए किसी भी बीज के लिए संख्याओं के समान अनुक्रम को वापस कर देगा। – TJD

+1

ठीक है, ब्रावो, यह सच है। लेकिन उदाहरण को छोटा और पठनीय रखने के लिए, मैंने बीज का उपयोग नहीं किया। – Mike

+0

आपको 'getRandomNumber'' के लिए '__wrap_foo' का नाम बदलने की आवश्यकता है। (http://xkcd.com/221/) –

उत्तर

8

आप या तो भी extern "C" समारोह आप रैप करने के लिए (है कि यदि संभव है) चाहते हैं या आप घायल नाम रैप करने के लिए की जरूरत है, उदाहरण के लिए, __wrap__Z3foov और फिर --wrap=_Z3foov लिंकर को पास किए जाने पर विचार किया है।

अंडरस्कोर सही प्राप्त करना थोड़ा मुश्किल है। यह मेरे लिए काम करता है:

$ 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

सी लिंक करने के लिए सी लिंकेज सी ++ फ़ंक्शन एक विकल्प नहीं है क्योंकि यह फ़ंक्शन ओवरलोड हो सकता है और इसे अन्य C++ फ़ंक्शंस से कॉल करना अभी भी संभव होना चाहिए। मैंने उलझन में नाम लपेटने की कोशिश की, लेकिन यह काम नहीं करता है। मैंने जो किया वह यह है: 'बाहरी "सी" int __wrap__Z3foov (शून्य) { \t वापसी 4; } शून्य इस Iestest() { जोर दें 5 == giveMeANumber(); } 'लिंकर विकल्प' -Xlinker --wrap = _Z3foov' के साथ मिलकर। दुर्भाग्य से, असली 'foo' फ़ंक्शन अभी भी कहा जा रहा है। कोई विचार? – Mike

+0

मैंने एक उदाहरण जोड़ा। सभी अंडरस्कोर सही पाने के लिए मुझे थोड़ी देर लग गई। – smparkes

+0

और प्रश्न के लिए धन्यवाद। मुझे - लपेटने के बारे में भी पता नहीं था। बहुत अच्छा। – smparkes

1

ऐसा लगता है कि आप परीक्षण के लिए कार्यों और कक्षाओं का नकल करने की कोशिश कर रहे हैं। आप उपयोग कर Google Mock

+1

Google मॉक का उपयोग करना मेरे लिए एक विकल्प नहीं है। मैं इसे पूरी तरह से जीएनयू लिंकर की मदद से पूरा करना चाहता हूं। – Mike