2011-10-05 23 views
7

मैं CreateFile() का उपयोग कर एक सीरियल पोर्ट खोल रहा हूं। मुझे एक टेस्टकेस (पुनर्वितरण के लिए बहुत जटिल) मिला है जो CreateFile()INVALID_HANDLE_VALUE और GetLastError() को ERROR_SUCCESS वापस करने के लिए लगातार CreateFile() का कारण बनता है। इसकी प्रकृति से, यह बग केवल तभी होता है जब एक थ्रेड उसी समय पोर्ट को खुलता है जब एक और बंदरगाह बंद हो जाता है। बंदरगाह खोलने वाला थ्रेड इस समस्या से चलता है।CreateFile() INVALID_HANDLE_VALUE लौटाता है लेकिन GetLastError() ERROR_SUCCESS

मुझे नहीं पता कि इससे कोई फर्क पड़ता है, लेकिन बाद में कोड में मैं CreateIoCompletionPort का उपयोग कर पोर्ट को एक CompletionPort से जोड़ता हूं।

HANDLE port = CreateFile(L"\\\\.\\COM1", 
         GENERIC_READ | GENERIC_WRITE, 
         0,     // must be opened with exclusive-access 
         0,     // default security attributes 
         OPEN_EXISTING,  // must use OPEN_EXISTING 
         FILE_FLAG_OVERLAPPED, // overlapped I/O 
         0);     // hTemplate must be NULL for comm devices 
if (port == INVALID_HANDLE_VALUE) 
{ 
    DWORD errorCode = GetLastError(); 
    cerr << L"CreateFile() failed with error: " << errorCode << endl; 
} 

मैं यकीन है कि बात यह है कि इस तरह की नहीं होना चाहिए हूँ:

यहाँ मेरी कोड है। क्या मैं गलत हूं? मैं सही परिणाम वापस करने के लिए एपीआई कैसे प्राप्त करूं?


अधिक विवरण:

JLong SerialChannel::nativeOpen(String name) 
{ 
    cerr << "nativeOpen(" << name << ")" << endl; 
    wstring nameWstring = name; 
    HANDLE port = CreateFile((L"\\\\.\\" + nameWstring).c_str(), 
     GENERIC_READ | GENERIC_WRITE, 
     0,           // must be opened with exclusive-access 
     0,           // default security attributes 
     OPEN_EXISTING,     // must use OPEN_EXISTING 
     FILE_FLAG_OVERLAPPED,  // overlapped I/O 
     0);           // hTemplate must be NULL for comm devices 
    cerr << "nativeOpen.afterCreateFile(" << name << ")" << endl; 
    cerr << "port: " << port << ", errorCode: " << GetLastError() << endl; 
    if (port == INVALID_HANDLE_VALUE) 
    { 
     DWORD errorCode = GetLastError(); 

     switch (errorCode) 
     { 
      case ERROR_FILE_NOT_FOUND: 
       throw PeripheralNotFoundException(jace::java_new<PeripheralNotFoundException>(name, Throwable())); 
      case ERROR_ACCESS_DENIED: 
      case ERROR_SHARING_VIOLATION: 
       throw PeripheralInUseException(jace::java_new<PeripheralInUseException>(name, Throwable())); 
      default: 
      { 
       throw IOException(jace::java_new<IOException>(L"CreateFile() failed with error: " + 
        getErrorMessage(GetLastError()))); 
      } 
     } 
    } 

    // Associate the file handle with the existing completion port 
    HANDLE completionPort = CreateIoCompletionPort(port, ::jperipheral::worker->completionPort, Task::COMPLETION, 0); 
    if (completionPort==0) 
    { 
     throw AssertionError(jace::java_new<AssertionError>(L"CreateIoCompletionPort() failed with error: " + 
      getErrorMessage(GetLastError()))); 
    } 
    cerr << "nativeOpen.afterCompletionPort(" << name << ")" << endl; 

    // Bind the native serial port to Java serial port 
    SerialPortContext* result = new SerialPortContext(port); 
    cerr << "nativeOpen.afterContext(" << name << ")" << endl; 
    return reinterpret_cast<intptr_t>(result); 
} 

: JPeripheral

यहाँ वास्तविक (unsanitized) स्रोत-कोड है: यह कोड एक सीरियल पोर्ट पुस्तकालय मैं विकसित किया है से लिया जाता है यहां वास्तविक आउटपुट है:

nativeOpen(COM1) 
nativeOpen.afterCreateFile(COM1) 
port: 00000374, errorCode: 0 
nativeOpen.afterCompletionPort(COM1) 
nativeOpen.afterContext(COM1) 
[...] 
nativeOpen(COM1) 
nativeOpen.afterCreateFile(COM1) 
port: FFFFFFFF, errorCode: 0 
java.io.IOException: CreateFile() failed with error: The operation completed successfully. 
+0

क्या ये लाइनें आपके परीक्षण में सटीक हैं जिनका उपयोग आप कर रहे हैं? कोई भी सरलीकरण (यहां तक ​​कि स्पष्ट रूप से हानिरहित वाले) समस्या के स्रोत को छुपा सकते हैं। –

+0

आप जिस हार्डवेयर को एक्सेस कर रहे हैं वह क्या है? – Gabe

+0

@Gabe: मैं एक एम्बेडेड डिवाइस तक पहुंच रहा हूं जिसे हमने घर में विकसित किया है। इसमें एक मानक डीबी 9 सीरियल-पोर्ट कनेक्शन है जिसे मैंने अपने पीसी से जोड़ा है (यहां कोई यूएसबी-आरएस 232 एडेप्टर नहीं है)। – Gili

उत्तर

8
HANDLE port = CreateFile(...); 
cerr << "nativeOpen.afterCreateFile(" << name << ")" << endl; 
cerr << "port: " << port << ", errorCode: " << GetLastError() << endl; 
if (port == INVALID_HANDLE_VALUE) 
{ 
    DWORD errorCode = GetLastError(); 

सीर के आउटपुट हुड के नीचे winapi कॉल को आमंत्रित करता है। जो GetLastError() द्वारा लौटाए गए थ्रेड त्रुटि मान को रीसेट करेगा। फिक्स:

HANDLE port = CreateFile(...); 
int err = GetLastError(); 
// etc, use err instead... 
+0

मुझे विश्वास नहीं है। मूल कोड जिसमें इस समस्या थी, में कोई 'cerr' निर्देश नहीं था। मैंने हाल ही में इसे जोड़ा है। क्या आप उपरोक्त कोड (शून्य 'सीर') के साथ कुछ भी गलत देखते हैं? – Gili

+1

आपके द्वारा दिखाए गए आउटपुट ट्रेस को केवल उस कोड द्वारा उत्पन्न किया जा सकता है जो * GetLastError मान को गड़बड़ कर देता है। मुझे संदेह नहीं है कि यह असफल हो सकता है, असफल होने के लिए COM पोर्ट खोलने के कई कारण हैं। –

+0

आप सही थे। मूल कोड 'फेंक IOException' (jace :: java_new (एल "CreateFile() त्रुटि के साथ असफल रहा:" + getErrorMessage (GetLastError()))। ध्यान दें कि विफलता के बिंदु और 'GetLastError' के पढ़ने के बीच कितना कोड मौजूद है() 'मूल्य को पढ़ना जल्द ही समस्या को ठीक करता है। धन्यवाद! – Gili