2010-11-16 13 views
9

हाल ही में मैं सभी चेतावनियों को सक्षम करने के /Wall Visual C++ option का उपयोग करने की कोशिश की और पाया कि निम्न कोड:FARPROC के साथ GetProcAddress को कॉल के आसपास C4191 चेतावनी को कैसे संबोधित करें?

typedef BOOL (WINAPI * TIsWow64ProcessFunction)(HANDLE, BOOL*); 
TIsWow64ProcessFunction isWow64ProcessFunction = reinterpret_cast<TIsWow64ProcessFunction> (
    ::GetProcAddress(kernel32DllHandle, "IsWow64Process")); 

पैदा की C4191:

warning C4191: 'reinterpret_cast' : unsafe conversion from 'FARPROC' to 'TIsWow64ProcessFunction' 
Calling this function through the result pointer may cause your program to fail 

अगर मैं एक सी शैली डाली का उपयोग एक ही चेतावनी दिखाई देता है, लेकिन अब यह "reinterpret_cast" के बजाय "प्रकार कास्ट" का उल्लेख करता है।

किसी भी मामले के लिए एक ही चेतावनी दोहराई जाती है जिसे मैं GetProcAddress() पर कॉल करता हूं और इसके वापसी मूल्य को कुछ उपयोग करने योग्य फ़ंक्शन पॉइंटर में परिवर्तित करता हूं।

मैं इन चेतावनियों को कैसे संबोधित करूं? क्या मुझे अपने कोड में बदलाव करने की ज़रूरत है?

+0

#pragma चेतावनी (निष्क्रिय कर दें: 4191) उपयुक्त लग रहा है लक्ष्य 0 चेतावनी तक पहुँचने के लिए है अगर: यह विशेष रूप से चेतावनी थेरेस के रूप में बेकार नहीं (स्पष्ट) जिस तरह से है, जबकि कार्यक्षमता रखने यह से बचना है। –

+0

क्या यह आपके लिए चेतावनी को आग लगाता है? मैंने कभी भी दीवार/दीवार, वीएस में केवल पी 4 चेतावनी स्तर का उपयोग नहीं किया। टाइपपीफ बूल (विनिपी * डिस्बलेरडर) (पीवीओआईडी *); डिस्बलेरिएडर fpnDisableRedir = NULL; fpnDisableRedir = (DISABLEREDIR) GetProcAddress (hKernel32, "Wow64DisableWow64FsRedirection"); – Kra

+1

@ क्रा: हाँ, यह सी 4191 के साथ/दीवार बनाता है। कुंजी सी 4191 डिफ़ॉल्ट रूप से अक्षम है और/दीवार इसे सक्षम बनाता है। – sharptooth

उत्तर

6

आप तर्क के साथ एक फ़ंक्शन पॉइंटर में एक FARPROC (फ़ंक्शन पॉइंटर के साथ कोई तर्क नहीं) कास्टिंग कर रहे हैं। आम तौर पर ऐसा करने के लिए यह एक बेहद बेवकूफ चीज है जो शायद भ्रष्टाचार को ढंकने में परिणाम देगी।

अब यह पता चला है कि GetProcAddress() वास्तव में एक FARPROC नहीं लौटाता है और आप वास्तव में जानते हैं कि आप क्या कर रहे हैं - लेकिन संकलक को यह नहीं पता है और यह आपको चेतावनी देने के लिए बाध्य है।

एकमात्र तरीका जिसे आप चुप कर सकते हैं वह चेतावनी को बंद करने के लिए #pragma या एक कंपाइलर स्विच का उपयोग कर रहा है। यह बदसूरत और गन्दा है, लेकिन यह आपके लिए विंडोज प्रोग्रामिंग है। :-)

+0

लिनक्स पर 'dlsym' बेहतर है? – Mehrdad

+0

dlsym एक शून्य पॉइंटर देता है इसलिए मुझे नहीं लगता कि संकलक चेतावनी देगा। यह मानता है कि एक शून्य * एक समारोह सूचक के रूप में बड़ा है। मुझे नहीं पता कि यह हमेशा सच है या नहीं। मुझे नहीं लगता कि मानक इसकी गारंटी देता है। –

+0

वीएस 2010 इसे एक त्रुटि के रूप में रिपोर्ट करता है। #pragma इस मुद्दे को हल करने में मदद नहीं कर रहा है। – null

2

मूल रूप से संकलक गारंटी नहीं दे सकता कि फ़ंक्शन उचित प्रकार का है, इसलिए परिणामस्वरूप पॉइंटर को कॉल करना आपके लिए असुरक्षित है। हालांकि, एक वीएस प्रोग्राम में आपको विंडोज़ के खिलाफ लिंक या लोड करने की ज़रूरत नहीं है। डीएलएस स्पष्ट रूप से, वे आपके लिए लोड हो जाएंगे और विंडोज हेडर में कोई भी फ़ंक्शन हमेशा उपयोग के लिए उपलब्ध होगा।

+1

मान लीजिए कि मैं वास्तव में लाइब्रेरी को गतिशील रूप से लोड करने के लिए तैयार हूं। चेतावनी के साथ मैं क्या करूँ? क्या मैं इसे अनदेखा करता हूं? क्या चेतावनी का मतलब यह है कि यह सुनिश्चित करने के लिए मेरे पास निर्भर है कि कार्यान्वयन में वास्तव में सही हस्ताक्षर है? – sharptooth

+0

@ शार्पतोथ: असल में, हां। इस समस्या का एकमात्र समाधान एक डीएलएल की स्थिर लोडिंग है- जो विंडोज हेडर के साथ होता है। – Puppy

+0

@ पुप्पी - आप 'GetprocAddress' के परिणाम को 'शून्य *' पर डाल सकते हैं। वह सी 4191 चेतावनी स्क्वैश करेगा। फिर, इसे फ़ंक्शन पॉइंटर प्रकार पर डालें। – jww

5

जैसा कि अन्य उत्तरों पहले ही उल्लेख कर चुके हैं, यह एक उपयोगी चेतावनी है। Normally, this type of coercion would be a serious bug hiding in your application

इसलिए, आप शायद इसे एक कंपाइलर स्विच के साथ विश्व स्तर पर अक्षम नहीं करना चाहते हैं। फिर भी आपको अभी भी GetProcAddress पर कॉल करने की आवश्यकता है, और आप चेतावनियों के बिना साफ रूप से संकलित करने के लिए अपने निर्माण को पसंद करते हैं।

  1. दबाने प्रत्येक व्यक्ति चेतावनी एक MSVC विशेष pragma का उपयोग कर:

    आप दो अच्छा विकल्प हैं। ,

    #pragma warning(suppress: 4191) 
    

    इस कोड केवल की बहुत अगली पंक्ति के लिए चेतावनी को दबा सुनिश्चित करना है कि यह विश्व स्तर पर दबा नहीं है और आप अभी भी यह करना होगा: सिर्फ बदनाम डाली ऊपर एक नई लाइन में, निम्न कोड जोड़ें अगर आप कोड बेस में कहीं और बेवकूफ कुछ करने की कोशिश करते हैं तो चेतावनी प्राप्त करें। बेशक, आपको प्रत्येक बार GetProcAddress का उपयोग करने की आवश्यकता होगी, जो कि दर्द का प्रकार है। इससे भी बदतर, यह एक गैर-पोर्टेबल, एमएसवीसी-विशिष्ट एक्सटेंशन है जो आपके कोड को गले लगाता है।

    तो वैकल्पिक रूप से और नरक;

  2. आप स्पष्ट रूप से void* को GetProcAddress (एक FARPROC) का परिणाम कास्टिंग, और फिर कास्टिंग द्वारा चेतावनी मौन कर सकते हैं कि विशेष समारोह-सूचक प्रकार के void*। उदाहरण के लिए:

    typedef BOOL (__stdcall *TIsWow64ProcessFunction)(HANDLE, BOOL*); 
    
    TIsWow64ProcessFunction isWow64ProcessFunction = 
        reinterpret_cast<TIsWow64ProcessFunction>(
         reinterpret_cast<void*>(
         ::GetProcAddress(hInstance, "IsWow64Process"))); 
    

    यह दृष्टिकोण अन्य compilers के साथ काम करेंगे, थोड़ा कम बदसूरत है, और यकीनन अधिक शब्दार्थ सार्थक है।

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