Winapi CreateFile()返回无效的\u句柄\u值,但GetLastError()为错误\u成功
我正在使用打开一个串行端口。我有一个测试用例(太复杂了,无法重新分发),它总是导致Winapi CreateFile()返回无效的\u句柄\u值,但GetLastError()为错误\u成功,winapi,serial-port,createfile,iocp,getlasterror,Winapi,Serial Port,Createfile,Iocp,Getlasterror,我正在使用打开一个串行端口。我有一个测试用例(太复杂了,无法重新分发),它总是导致CreateFile()返回INVALID\u HANDLE\u VALUE和GetLastError()返回ERROR\u SUCCESS。从外观上看,只有当一个线程在另一个端口关闭端口的同时打开端口时,才会出现此错误。打开端口的线程遇到此问题 我不知道这是否有区别,但在后面的代码中,我使用将端口与CompletionPort关联起来 这是我的密码: HANDLE port = CreateFile(L"\\\\
CreateFile()
返回INVALID\u HANDLE\u VALUE
和GetLastError()
返回ERROR\u SUCCESS
。从外观上看,只有当一个线程在另一个端口关闭端口的同时打开端口时,才会出现此错误。打开端口的线程遇到此问题
我不知道这是否有区别,但在后面的代码中,我使用将端口与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;
}
这些线就是你在测试中使用的线吗?任何简化(甚至表面上无害的简化)都可能隐藏问题的根源。您正在访问的硬件是什么?@Gabe:我正在访问我们内部开发的嵌入式设备。它有一个标准的DB9串行端口连接,我已经连接到我的电脑(这里没有USB-RS232适配器)。@David:我已经发布了完整的源代码供你审阅。你必须在
CreateFile
faliure之后立即调用GetLastError
,没有我不相信。出现此问题的原始代码不包含任何cerr
指令。我最近才补充说。您是否看到上面的代码(减去cerr
)有任何错误?您显示的输出跟踪只能由弄乱GetLastError值的代码生成。我不怀疑它会失败,打开COM端口失败有很多原因。你是对的。调用的原始代码抛出IOException(jace::java_new(L“CreateFile()失败,出现错误:“+getErrorMessage(GetLastError()))
。请注意,在失败点和读取GetLastError()之间存在多少代码
。尽早读取值解决了问题。谢谢!我也遇到过类似的情况,尽管CreateFile2和GetLastError()之间只有“new wchar\u t[messageLength]”。这足以重置GetLastError()返回的错误消息。
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.
HANDLE port = CreateFile(...);
cerr << "nativeOpen.afterCreateFile(" << name << ")" << endl;
cerr << "port: " << port << ", errorCode: " << GetLastError() << endl;
if (port == INVALID_HANDLE_VALUE)
{
DWORD errorCode = GetLastError();
HANDLE port = CreateFile(...);
int err = GetLastError();
// etc, use err instead...