c++ Std:: wstring पार DLL पार करने में असमर्थ



visual-studio-2010 visual-c++ (1)

मैंने एक मौजूदा एमएफसी डीएलएल के खिलाफ यूनिट टेस्ट लिखने के लिए विजुअल स्टूडियो 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 परीक्षण के तहत एमएफसी डीएलएल से निर्यात किया गया वर्ग है हालांकि, परीक्षण ढांचा एक अप्रत्याशित अपवाद की रिपोर्ट करता है। मैं इसे नीचे std::wstring की प्रतिलिपि निर्माता के लिए ट्रैक कर रहा था जब स्ट्रिंग को Foobar के निर्माता को कॉपी करते समय MSVC डीबगर स्रोत स्ट्रिंग को <Bad Ptr> रूप में रिपोर्ट करता है

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

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


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

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

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





dll