2010-02-23 14 views
12

मेरे पास कुछ सी ++ कोड है जिसमें CreateDirectory(). नामक एक विधि शामिल है, पहले कोड केवल एसटीएल और बूस्ट का इस्तेमाल करता था, लेकिन मुझे हाल ही में <windows.h> शामिल करना था ताकि मैं CSIDL_LOCAL_APPDATA देख सकूं।मैं विंडोज हेडर फ़ाइलों में परिभाषित मैक्रोज़ के साथ नाम टकराव से कैसे बचूं?

अब, यह कोड:

filesystem.CreateDirectory(p->Pathname()); // Actually create it... 

अब संकलित:

error C2039: 'CreateDirectoryA' : is not a member of ... 

कौन सा winbase.h में इस मैक्रो से मेल खाती है:

#ifdef UNICODE 
#define CreateDirectory CreateDirectoryW 
#else 
#define CreateDirectory CreateDirectoryA 
#endif // !UNICODE 

पूर्व प्रोसेसर मेरी विधि को फिर से परिभाषित किया गया है कहते हैं। क्या इस नामकरण टकराव से बचने का कोई संभावित तरीका है? या मुझे अपने CreateDirectory() विधि का नाम बदलना है?

+6

अब आप जानते हैं कि क्यों Bjarne Stroustrup सी ++ से सी प्री-प्रोसेसर से छुटकारा पाना चाहता है - 'सी ++ के डिजाइन और विकास' देखें। –

+0

उत्तर के साथ संभावित डुप्लिकेट: http://stackoverflow.com/questions/1394910/how-to-tame-the-windows-headers-useful-defines –

+0

कृपया इसे वोट दें: http://visualstudio.uservoice.com/forums/121579-विज़ुअल-स्टूडियो/सुझाव/6656174-windows-h-that-doesn-t-define-ma –

उत्तर

12

यदि आप अपनी CreateDirectory विधि का नाम बदलते हैं तो आप बेहतर होंगे। यदि आपको विंडोज एपीआई का उपयोग करने की आवश्यकता है, तो विंडोज़ के साथ लड़ना एक हारने वाली लड़ाई है।

संयोग से, यदि आप लगातार windows.h सहित हैं, तो यह अभी भी संकलित होगा। (हालांकि आपको अन्य स्थानों में समस्या हो सकती है)।

+0

+1 लगातार windows.h सहित, और यदि मैं कर सकता हूं, +1 के लिए इससे लड़ने और बचने के लिए नामकरण नहीं किया गया ... मुझे इस समस्या को 'इनिशिएटशूटडाउन()' के साथ था और नई समस्याओं के कारण काम करने के सभी प्रयासों के कारण। –

+1

कभी-कभी एमएस द्वारा उठाए गए नाम के अलावा बेहतर नाम ढूंढना मुश्किल होता है। – user1633272

7

आप एक मॉड्यूल जिनका एकमात्र उद्देश्य #include <windows.h> है बना सकते हैं और एक समारोह में लिपटे CSIDL_LOCAL_APPDATA देख सकता है।

int get_CSIDL_LOCAL_APPDATA(void) 
{ 
    return CSIDL_LOCAL_APPDATA; 
} 

btw, अच्छी तरह से बाहर काम कर रहा है कि क्या हुआ के लिए किया है!

+0

चालाक समाधान। –

-2
#pragma push_macro("CreateDirectory") 

यदि कुछ भी काम नहीं करता है, तो आप नाम बदलने के बजाय अपने कार्यों के लिए अपना नामस्थान इस्तेमाल कर सकते हैं।

+2

एक नामस्थान इस समस्या को ठीक नहीं करेगा। प्रीप्रोसेसर कुछ और चीज़ों के लिए अपनी CreateDirectory विधि का नाम बदल रहा है। –

+0

आप सही हैं, मुझे समस्या गलत है। मेरा समाधान सिर्फ नाम बदलने के लिए कुछ खराब विकल्प था। – AureliusMarcus

1

एक क्रॉस प्लेटफ़ॉर्म कोडबेस पर काम कर रहे डेवलपर के रूप में, यह एक समस्या है। इसके साथ निपटने का एकमात्र तरीका

  • सुनिश्चित करें कि विंडोज़ पर - विंडोज़ कम से कम - सार्वभौमिक रूप से शामिल है। फिर CreateDirectory मैक्रो को आपके संकलन इकाइयों में से प्रत्येक में परिभाषित किया गया है और इसे CreateDirectoryW के साथ सार्वभौमिक रूप से प्रतिस्थापित किया गया है। Precompiled हेडर, इस

के लिए आदर्श हैं या कि अगर एक अप्रिय प्रस्ताव है, (और यह मेरे लिए है) खिड़कियों विशिष्ट उपयोगिता फ़ाइलों में

  • अलग windows.h उपयोग। बुनियादी आवश्यक कार्यक्षमता निर्यात करने वाली फ़ाइलें बनाएं। हेडर फ़ाइलों को डेटा प्रकारों का उपयोग करना चाहिए जो कि संगत हैं, लेकिन windows.h को शामिल करने पर निर्भर नहीं हैं। सीपीपी कार्यान्वयन फ़ाइल (स्पष्ट रूप से) windows.h का उपयोग करना चाहिए।

अपने utlility कार्यों परस्पर विरोधी प्रतीकों के साथ परियोजना हेडर फाइल को शामिल करने की जरूरत है उसके बाद निम्न पैटर्न एक आवश्यकता है:

#include <windows.h> 
#ifdef CreateDirectory 
#undef CreateDirectory 
#endif 
// etc 
#include "some_class_with_CreateDirectory_method.h" 
// ... 

फिर आप स्पष्ट रूप से किसी भी Windows API कार्यों की गैर मैक्रो संस्करण को कॉल करना होगा आप # undef'd है - CreateDirectoryA या डब्ल्यू आदि

0

push मैक्रो, undef यह और pop फिर मैक्रो:

#pragma push_macro("CreateDirectory") 
#undef CreateDirectory 
void MyClass::CreateDirectory() 
{ 
// ... 
} 
#pragma pop_macro("CreateDirectory") 
0

ध्यान दें कि नाम संघर्ष आमतौर पर शामिल होने वाली एक निश्चित शीर्षलेख फ़ाइल से आता है। तब तक CreateDirectory और GetMessage जैसी चीजें बिना किसी समस्या के दृश्यता और कोड संकलन में खींची जाती हैं।

आप एक रैपर हेडर फ़ाइल में इस तरह के समावेशन को अलग कर सकते हैं और इसके अंत में "#undef जो कुछ भी" अलग कर सकते हैं। फिर, आपके पास जो भी नाम टकराव होगा, वह चलेगा। बेशक, आपको अपने मैक्रोज़ को अपने कोड में उपयोग करने की आवश्यकता नहीं है (हाँ, बहुत संभावित ...)

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