खोज…


टिप्पणियों

प्रत्येक थ्रेड का अपना अंतिम त्रुटि कोड होगा। Windows API कॉलिंग थ्रेड पर अंतिम त्रुटि कोड सेट करेगा।

Windows API फ़ंक्शन के रिटर्न मान की जांच करने के तुरंत बाद आपको हमेशा GetLastError फ़ंक्शन को कॉल करना चाहिए।

जब वे विफल होते हैं, तो अधिकांश Windows API फ़ंक्शन अंतिम त्रुटि कोड सेट करते हैं। कुछ सफल होने पर अंतिम त्रुटि कोड भी सेट करेंगे। ऐसे कई फ़ंक्शन हैं जो अंतिम त्रुटि कोड सेट नहीं करते हैं। हमेशा Windows API फ़ंक्शन के दस्तावेज़ देखें।

त्रुटि कोड का विवरण प्राप्त करने के लिए FormatMessage फ़ंक्शन का उपयोग करते समय FORMAT_MESSAGE_FROM_SYSTEM बिना FORMAT_MESSAGE_IGNORE_INSERTS का उपयोग करना असुरक्षित है।

परिचय

Windows API C-callable इंटरफ़ेस के माध्यम से प्रदान किया गया है। एपीआई कॉल की सफलता या विफलता की वापसी मूल्यों के माध्यम से कड़ाई से रिपोर्ट की जाती है। अपवाद दस्तावेज अनुबंध का हिस्सा (हालांकि कुछ एपीआई कार्यान्वयन बढ़ा सकते हैं नहीं कर रहे हैं SEH अपवाद हैं, जैसे जब करने के लिए केवल पढ़ने के लिए lpCommandLine तर्क गुजर CreateProcess )।

मोटे तौर पर रिपोर्ट करने में त्रुटि चार श्रेणियों में से एक में आती है:

प्रत्येक एपीआई कॉल के लिए प्रलेखन स्पष्ट रूप से कॉल करता है, त्रुटियों की रिपोर्ट कैसे की जाती है। हमेशा प्रलेखन से परामर्श करें।

केवल रिटर्न मान द्वारा रिपोर्ट की गई त्रुटि

कुछ API कॉल बिना किसी अतिरिक्त जानकारी (जैसे GetObject ) के बिना एक एकल विफलता / सफलता ध्वज लौटाते हैं:

if ( GetObjectW( obj, 0, NULL ) == 0 ) {
    // Failure: no additional information available.
}

विफलता पर अतिरिक्त जानकारी के साथ त्रुटि रिपोर्ट की गई

विफलता / सफलता वापसी मूल्य के अलावा, कुछ एपीआई कॉल विफलता पर अंतिम त्रुटि भी निर्धारित करते हैं (जैसे CreateWindow )। प्रलेखन में आमतौर पर इस मामले के लिए निम्नलिखित मानक शब्द हैं:

यदि फ़ंक्शन सफल होता है, तो वापसी मूल्य <एपीआई-विशिष्ट सफलता मूल्य> है
यदि फ़ंक्शन विफल रहता है, तो वापसी मान <API- विशिष्ट त्रुटि मान> है । विस्तारित त्रुटि जानकारी प्राप्त करने के लिए, GetLastError पर कॉल करें।

if ( CreateWindowW( ... ) == NULL ) {
    // Failure: get additional information.
    DWORD dwError = GetLastError();
} else {
    // Success: must not call GetLastError.
}

यह महत्वपूर्ण है कि आप GetLastError() IMMEDIATELY को कॉल करें। पिछले त्रुटि कोड किसी अन्य समारोह द्वारा ओवरराइट किया जा सकता है, इसलिए अगर कोई समारोह है कि विफल रही है और करने के लिए कॉल के बीच एक अतिरिक्त समारोह कॉल GetLastError() , से वापसी GetLastError() नहीं रह विश्वसनीय हो जाएगा। C ++ कंस्ट्रक्टर्स के साथ काम करते समय अतिरिक्त सावधानी बरतें।

एक बार जब आप एक त्रुटि कोड प्राप्त करते हैं, तो आपको इसकी व्याख्या करने की आवश्यकता होगी। आप सिस्टम त्रुटि कोड (विंडोज) पेज पर MSDN पर त्रुटि कोड की एक व्यापक सूची प्राप्त कर सकते हैं। वैकल्पिक रूप से, आप अपने सिस्टम हेडर फ़ाइलों में देख सकते हैं; सभी त्रुटि कोड स्थिरांक के साथ फ़ाइल winerror.h । (यदि आपके पास विंडोज 8 या नए के लिए माइक्रोसॉफ्ट का आधिकारिक एसडीके है, तो यह शामिल फ़ोल्डर के shared सबफ़ोल्डर में है)।

अन्य प्रोग्रामिंग भाषाओं में GetLastError() कॉल करने पर नोट्स

.net भाषाएँ (C #, VB, आदि)

.Net के साथ, आपको सीधे GetLastError() P / Invoke नहीं करना चाहिए । ऐसा इसलिए है क्योंकि .net रनटाइम आपकी पीठ के पीछे एक ही धागे पर अन्य विंडोज एपीआई कॉल करेगा। उदाहरण के लिए, कचरा संग्राहक VirtualFree() को कॉल कर सकता है यदि उसे पर्याप्त मेमोरी मिलती है जिसे वह अब उपयोग नहीं कर रहा है, और यह आपके इच्छित फ़ंक्शन कॉल और GetLastError() बीच आपकी कॉल के बीच हो सकता है

इसके बजाय, .net Marshal.GetLastWin32Error() प्रदान करता है। Marshal.GetLastWin32Error() फ़ंक्शन, जो आपके द्वारा किए गए अंतिम P / Invoke कॉल से अंतिम त्रुटि को पुनर्प्राप्त करेगा। सीधे GetLastError() कॉल करने के बजाय इसका उपयोग करें।

(.net वैसे भी आपको GetLastError() आयात करने से नहीं रोकता, मुझे यकीन नहीं है कि क्यों।)

जाओ

विभिन्न जाओ द्वारा प्रदान की सुविधा DLL कार्यों फोन करने के लिए (जो दोनों पैकेज में रहते हैं syscall और पैकेज golang.org/x/sys/windows :) तीन मान r1 , r2 , और errr2 का उपयोग कभी नहीं किया जाता है; आप वहां खाली पहचानकर्ता का उपयोग कर सकते हैं। r1 फ़ंक्शन का रिटर्न मान है। err GetLastError() को कॉल करने का परिणाम है, लेकिन एक प्रकार में परिवर्तित हो जाता है जो error लागू करता error , इसलिए आप इसे कॉलिंग फ़ंक्शन को हैंडल करने के लिए पास कर सकते हैं।

क्योंकि गो को पता नहीं है कि कब GetLastError() कॉल करना है और कब नहीं, यह हमेशा गैर- nil त्रुटि लौटाएगा। इसलिए, विशिष्ट गो त्रुटि-हैंडलिंग मुहावरा

r1, _, err := syscall.Syscall12(CreateWindowW.Addr(), ...)
if err != nil {
    // handle err
}
// use r1

काम नहीं करेगा। इसके बजाय, आप की जांच करना चाहिए r1 , जैसा कि आप सी में होगा वास्तव में, और केवल का उपयोग err है कि अगर यह संकेत करता है समारोह त्रुटि दी:

r1, _, err := syscall.Syscall12(CreateWindowW.Addr(), ...)
if r1 == 0 {
    // handle err
}
// use r1

विफलता और सफलता पर अतिरिक्त जानकारी के साथ त्रुटि रिपोर्ट की गई

कुछ एपीआई कॉल एक से अधिक तरीकों से सफल या विफल हो सकती हैं। एपीआई आमतौर पर दोनों सफल चालान के साथ-साथ त्रुटियों (जैसे क्रिएटमुटेक्स ) के लिए अतिरिक्त जानकारी लौटाते हैं

if ( CreateMutexW( NULL, TRUE, L"Global\\MyNamedMutex" ) == NULL ) {
    // Failure: get additional information.
    DWORD dwError = GetLastError();
} else {
    // Success: Determine which mutex was returned.
    if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
        // Existing mutex object returned.
    } else {
        // Newly created mutex object returned.
    }
}

HRESULT मान के रूप में रिपोर्ट की गई त्रुटि

HRESULT s संख्यात्मक 32-बिट मान हैं, जहाँ बिट्स या बिट पर्वतमाला अच्छी तरह से परिभाषित जानकारी को एनकोड करती हैं। MSB एक विफलता / सफलता ध्वज है, जिसमें शेष बिट्स अतिरिक्त जानकारी संग्रहीत करते हैं। विफलता या सफलता FAILED या SUCCEEDED मैक्रोज़ का उपयोग करके निर्धारित की जा सकती है। HRESULT s आमतौर पर COM के साथ उपयोग किया जाता है, लेकिन गैर-COM कार्यान्वयन में भी दिखाई देता है (जैसे StringCchPrintf )।

const size_t cchBuf = 5;
wchar_t buffer[cchBuf] = { 0 };
HRESULT hr = StringCchPrintfW( buffer, cchBuf, L"%s", L"Hello, world!" );
if ( FAILED( hr ) ) {
    // Failure: Determine specific reason.
    switch ( hr ) {
    case STRSAFE_E_INSUFFICIENT_BUFFER:
        // Buffer too small; increase buffer and retry.
        ...
    case STRSAFE_E_INVALID_PARAMETER:
        // Invalid parameter; implement custom error handling (e.g. logging).
        ...
    default:
        // Some other error code; implement custom error handling (e.g. logging).
        ...
    }
}

संदेश कोड में एक त्रुटि कोड परिवर्तित करना

GetLastError एक संख्यात्मक त्रुटि कोड देता है। एक वर्णनात्मक त्रुटि संदेश प्राप्त करने के लिए ( जैसे , उपयोगकर्ता को प्रदर्शित करने के लिए), आप FormatMessage को कॉल कर सकते हैं:

// This functions fills a caller-defined character buffer (pBuffer)
// of max length (cchBufferLength) with the human-readable error message
// for a Win32 error code (dwErrorCode).
// 
// Returns TRUE if successful, or FALSE otherwise.
// If successful, pBuffer is guaranteed to be NUL-terminated.
// On failure, the contents of pBuffer are undefined.
BOOL GetErrorMessage(DWORD dwErrorCode, LPTSTR pBuffer, DWORD cchBufferLength)
{
    if (cchBufferLength == 0)
    {
        return FALSE;
    }

    DWORD cchMsg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                                 NULL,  /* (not used with FORMAT_MESSAGE_FROM_SYSTEM) */
                                 dwErrorCode,
                                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                                 pBuffer,
                                 cchBufferLength,
                                 NULL);
    return (cchMsg > 0);
}

C ++ में , आप std::string class का उपयोग करके इंटरफ़ेस को काफी सरल बना सकते हैं:

#include <Windows.h>
#include <exception>
#include <stdexcept>
#include <memory>
#include <string>
typedef std::basic_string<TCHAR> String;

String GetErrorMessage(DWORD dwErrorCode)
{
    LPTSTR psz = NULL;
    const DWORD cchMsg = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
                                         | FORMAT_MESSAGE_IGNORE_INSERTS
                                         | FORMAT_MESSAGE_ALLOCATE_BUFFER,
                                       NULL, // (not used with FORMAT_MESSAGE_FROM_SYSTEM)
                                       dwErrorCode,
                                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                                       reinterpret_cast<LPTSTR>(&psz),
                                       0,
                                       NULL);
    if (cchMsg > 0)
    {
        // Assign buffer to smart pointer with custom deleter so that memory gets released
        // in case String's c'tor throws an exception.
        auto deleter = [](void* p) { ::HeapFree(::GetProcessHeap(), 0, p); };
        std::unique_ptr<TCHAR, decltype(deleter)> ptrBuffer(psz, deleter);
        return String(ptrBuffer.get(), cchMsg);
    }
    else
    {
        throw std::runtime_error("Failed to retrieve error message string.");
    }
}

नोट: ये फ़ंक्शन HRESULT मानों के लिए भी काम करते हैं । बस DWORD dwErrorCode से पहले पैरामीटर को HRESULT hResult । बाकी कोड अपरिवर्तित रह सकता है।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow