2009-12-08 12 views
7

ठीक है के रूप में लोड हो रहा है, तो यह एक abit मेरे साथ इतना नंगे व्याख्या करने के लिए लंबे समय से है ..सी ++: एक EXE एक DLL, स्थानीय vftable समस्या

मैं एक exe नामित test.exe जो आम तौर पर एक स्टैंड के रूप में प्रयोग किया जाता है है अकेले आवेदन मैं इस exe को एक अन्य अनुप्रयोग, app.exe के अंदर एक मॉड्यूल (एक डीएलएल) के रूप में उपयोग करना चाहता हूं।

test.exe में कोड बहुत आसान की तरह कुछ करता है:

void doTest() 
{ 
    MyClass *inst = new MyClass(); 
    inst->someMethod(); 
} 

कहाँ someMethod() आभासी है और MyClass एक आभासी डी 'टो है।
doTest() test.exe से निर्यात किया जाता है और इस प्रकार test.lib नामक एक lib को बनाया गया है
app.exe इस lib के साथ स्थैतिक रूप से test.exe लोड होने पर जुड़ा हुआ है।

जब मैं test.exe स्टैंड-अलोन चला रहा हूं तो यह ठीक है लेकिन जब मैं इसे एप.एक्सई से लोड कर रहा हूं तो यह क्रैश हो जाता है।
डीबगर के साथ कोड में कदम उठाने से पता चला कि क्रैश वर्चुअल विधि को कॉल में है। यह पता चला है कि vftable किसी भी तरह खराब हो जाता है।

कुछ जांच के बाद यह पता चला है कि जब MyClass के निर्माता के अंदर कोड चल रहा है, तो vftable एक बात है, लेकिन जब new पर कॉल करता है तो इसे "स्थानीय vftable" नामक किसी अन्य चीज़ के साथ प्रतिस्थापित किया जाता है। मुझे this obscure discussion about why this is मिला।

डीबगिंग के लगभग एक दिन बाद मुझे यह हुआ कि इस "स्थानीय vftable" में पॉइंटर्स दोनों मामलों में समान हैं, जब test.exe अकेले खड़ा होता है और जब मॉड्यूल को मॉड्यूल के रूप में लोड किया जाता है। यह सही नहीं हो सकता है क्योंकि test.exe को एक अलग पते में लोड किया गया है ...
इस सिद्धांत का परीक्षण करने के लिए मैंने लिंकर विकल्पों में लोडिंग पता बदल दिया है जहां test.exe लोड होता है जब यह app.exe में होता है और अब, देखो और देखो, सब कुछ काम करता है।

जाहिर है, यह स्थायी समाधान नहीं है क्योंकि अगली बार यह यादृच्छिक रूप से चयनित पता पर कब्जा कर लिया जा सकता है और वही समस्या फिर से हो जाएगी।

तो मेरा प्रश्न: यह "स्थानीय vftable" exe के स्थिर लोडिंग पते से क्यों जुड़ा हुआ है? एक मॉड्यूल के रूप में एक exe लोड एक बुरी चीज लोड कर रहा है? exe क्यों मानता है कि यह अपने स्थिर पते पर भरा हुआ है?

बस संदर्भ के लिए: यह सब एमएसवीसी 2008, विंडोज एक्सपी x64 के साथ किया जाता है।

उत्तर

3

मैं जिस वर्कअराउंड का उपयोग कर रहा हूं वह केवल एक संकलन कॉन्फ़िगरेशन जोड़ना है और इसे एक जैसे कार्य करने के लिए मजबूर करने के बजाय exe को वास्तविक डीएल के रूप में संकलित करना है।

/fixed:no का उपयोग किसी कारण से समस्या का समाधान नहीं किया।

एक्सिस और डीएलएल के बीच एक और अंतर यह है कि प्रवेश बिंदु अलग है। एक डीएलएल का प्रवेश बिंदु DllMain है जहां एक exe के रूप में सीआरटी में प्रवेश बिंदु है जो अंततः मुख्य() या WinMain() कहते हैं।

4

वीसी ++ डिफ़ॉल्ट रूप से .exes से स्थान जानकारी को स्ट्रिप करता है क्योंकि आम तौर पर उन्हें स्थानांतरित करने की आवश्यकता नहीं होती है।

आप इसे रिलायंस जानकारी को/निश्चित के साथ बनाए रखने के लिए मजबूर कर सकते हैं: नहीं। देखें: http://msdn.microsoft.com/en-us/library/w368ysh2.aspx

+2

मैंने कोशिश की लेकिन ऐसा कुछ कारणों से कोई प्रभाव नहीं प्रतीत होता – shoosh

संबंधित मुद्दे