2013-03-02 8 views
6

में std :: wstring पास करने में असमर्थ मैंने मौजूदा एमएफसी डीएलएल के खिलाफ यूनिट परीक्षण लिखने के लिए विजुअल स्टूडियो 2010 में एक प्रोजेक्ट स्थापित किया है। मैं एक सिंगल-हेडर यूनिट टेस्ट फ्रेमवर्क का उपयोग कर रहा हूं, और यूनिट टेस्ट प्रोजेक्ट से एमएफसी डीएलएल के लिब रैपर से जुड़ा हुआ हूं। मैं एक वर्ग बनाने की कोशिश कर रहा हूं जो इसके निर्माता में std::wstring लेता है।डीएलएल

TEST_CASE("MyProject/MyTest", "Do the test.") 
{ 
    MockDbService mockDbService; 
    Foobar foo(L"{F00DFACE-FEED-DEAD-BEEF-C0FFEEDECADE}", mockDbService); 

    foo.loadObject(); 

    REQUIRE(mockDbService.getMethodInvokeCount("query()") >= 1); 
} 

कहाँ Foobar कक्षा की परीक्षा के तहत MFC DLL से निर्यात किया है: यहाँ क्या अपने परीक्षण लग रहा है की तरह है। हालांकि, परीक्षण ढांचा एक अप्रत्याशित अपवाद की रिपोर्ट करता है। Foobar के कन्स्ट्रक्टर को स्ट्रिंग की प्रतिलिपि करते समय मैंने इसे std::wstring की कॉपी कन्स्ट्रक्टर तक ट्रैक किया। एमएसवीसी डीबगर स्रोत स्ट्रिंग को <Bad Ptr> के रूप में रिपोर्ट करता है।

मैंने एक डमी कन्स्ट्रक्टर, Foobar::Foobar(long num, IDbService& db) बनाया और सभी मान (IDbService& समेत) ठीक ठीक हो गए।

दोनों एमएफसी डीएलएल और मेरी यूनिट टेस्ट EXE एक संपत्ति शीट साझा कर रहे हैं जो कंपाइलर झंडे को बराबर रखना चाहिए। मैं डीबग मोड में परीक्षण और परीक्षण कर रहा हूं। कोई विचार क्यों std::wstring डीएलएल भर में कॉपी नहीं कर सकता है?

+2

क्या आप सीआरटी के डीबग संस्करण के साथ EXE और DLL दोनों को गतिशील रूप से जोड़ रहे हैं? ('/ MDd') –

+1

@ श्री सी 64 वाह, वह था। मेरा यूनिट टेस्ट प्रोजेक्ट '/ MD' का उपयोग कर रहा था और एमएफसी डीएलएल'/MDd' था। मुझे एक उत्तर के रूप में एक संक्षिप्त स्पष्टीकरण पसंद आएगा ताकि मैं इसे समझ सकूं; और मैं इसे स्वीकार करूंगा। धन्यवाद! –

+0

मैंने एक संक्षिप्त स्पष्टीकरण जोड़ा। असल में, मुझे लगता है कि आपके मामले में समस्या यह है कि डीबग-बिल्ड के 'std :: wstring' के रिलीज-बिल्ड की' std :: wstring' की तुलना में एक अलग कार्यान्वयन है। –

उत्तर

9

आपको लगता है कि दोनों EXE और DLL की जांच करनी चाहिए गतिशील ही डिबग सीआरटी (/MDd संकलक विकल्प) के साथ जुड़े। सुनिश्चित करें कि _HAS_ITERATOR_DEBUGGING जैसी अन्य सेटिंग्स भी EXE और DLL दोनों के लिए समान हैं।

(क्लास इंटरफ़ेस पर std::wstring के बजाय const wchar_t* का उपयोग करने के लिए शॉर्टकट का उपयोग किया जा सकता है, और केवल कन्स्ट्रक्टर के शरीर के अंदर कच्चे सूचक से std::wstring बनाएं)।

संपादित: आप कि सीआरटी बेमेल (अर्थात EXE /MD बनाम /MDd के साथ बनाया गया DLL के साथ बनाया) की पुष्टि की समस्या थी। तथ्य यह है कि एक ही कक्षा का नाम std::wstring का अर्थ है डीबग बिल्ड (/MDd) में दो अलग-अलग वर्ग और रिलीज में (/MD) बनाता है। वास्तव में, डीबग बनाने में डिबगिंग में सहायता के लिए कक्षा कार्यान्वयन के अंदर अतिरिक्त यांत्रिकी हो सकती है; यह यांत्रिकी अक्षमताएं पेश कर सकती है, इसलिए इसे रिलीज बिल्ड में हटा दिया गया है। इसलिए, डीबग बिल्ड की std::wstring की आंतरिक संरचना रिलीज बिल्ड के std::wstring से अलग है (उदाहरण के लिए यदि आप उदाहरणों के कच्चे sizeof को मुद्रित करने का प्रयास करते हैं, तो आप रिलीज बिल्ड और डिबग बिल्डों में अलग-अलग संख्याएं पा सकते हैं)। इसलिए, /MD के साथ निर्मित EXE रिलीज-बिल्ड की std::wstring की अपेक्षा कर रहा था; इसके बजाय /MDd के साथ बनाया गया डीएलएल डीबग-बिल्ड के std::wstring की अपेक्षा कर रहा था: इन दो उम्मीदों के बीच एक मेल नहीं है (एक मॉड्यूल कक्षा X कक्षा की अपेक्षा कर रहा है लेकिन अन्य मॉड्यूल कक्षा Y कक्षा दे रहा है) और इसलिए आपको एक क्रैश है।

+0

यह समझ में आता है। धन्यवाद। उस स्थिति में, मेरी समस्या ठीक है जो मैंने पहले पाया था: http://stackoverflow.com/questions/2322095/why-does-this-program-crash-passing-of-stdstring-between-dlls?rq=1 लेकिन मेरी दोनों परियोजनाएं डीबग में बनाई गई थीं इसलिए मुझे नहीं लगता था कि यह संबंधित था। आप जो कह रहे हैं उसके अनुसार, मैं डीबग परियोजनाओं के साथ भी सीआरटी के रिलीज निर्माण का उपयोग कर रहा था। एक बार फिर धन्यवाद। –

+1

हां, '/ MD' सीआरटी डीएलएल जारी करने के लिए गतिशील लिंकिंग है; '/ MDd' सीआरटी डीएलएल डीबग करने के लिए गतिशील लिंकिंग है। –