我打開一個串口使用CreateFile()。我有一個測試用例(太複雜,無法重新分配),導致CreateFile()
返回INVALID_HANDLE_VALUE
和GetLastError()
返回ERROR_SUCCESS
。從外觀上看,只有當一個線程在另一個端口關閉的同時打開端口時,纔會出現此錯誤。打開端口的線程遍歷這個問題。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;
}
我敢肯定這樣的事情不應該發生的。我做錯了什麼?我如何讓API返回正確的結果?
更多詳情:JPeripheral
下面是實際的(unsanitized)源代碼:
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);
}
此代碼是從一個串行端口庫我已經開發採取這裏是我得到的實際輸出:
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.
這些行是您在測試中使用的確切行嗎?任何簡化(甚至顯然無害)都可能隱藏問題的根源。 –
您訪問的硬件是什麼? – Gabe
@Gabe:我正在訪問我們內部開發的嵌入式設備。它有一個標準的DB9串行端口連接,我已連接到我的PC(這裏沒有USB-RS232適配器)。 – Gili