我们正在为xidobi串口项目实现一些winapi
方法的一对一映射。方法到 java的映射按预期工作,但由于未知原因被清除。C
GetLastError()
这是C代码:
// CreateFile ////////////////////////////////////////////////////////////
JNIEXPORT jint JNICALL
Java_org_xidobi_OS_CreateFile(JNIEnv *env, jobject this,
jstring lpFileName,
jint dwDesiredAccess,
jint dwShareMode,
jint lpSecurityAttributes,
jint dwCreationDisposition,
jint dwFlagsAndAttributes,
jint hTemplateFile) {
const char* fileName = (*env)->GetStringUTFChars(env, lpFileName, NULL);
HANDLE handle = CreateFile(fileName,
dwDesiredAccess,
dwShareMode,
(LPSECURITY_ATTRIBUTES) lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
(HANDLE) hTemplateFile);
(*env)->ReleaseStringUTFChars(env, lpFileName, fileName);
return (jint) handle;
}
// GetLastError ////////////////////////////////////////////////////////////
JNIEXPORT jint JNICALL
Java_org_xidobi_OS_GetLastError(JNIEnv *env, jobject this) {
return (jint) GetLastError();
}
在Java中,我们这样调用映射的本地方法:
int handle = os.CreateFile("\\\\.\\" + portName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (handle != INVALID_HANDLE_VALUE)
return handle;
int lastError= os.GetLastError(); //-> sometimes 0 (ERROR_SUCCESS)
我们发现如果我们在返回正确的错误代码GetLastError()
后立即调用 C。CreateFile(..)
由于一对一的映射非常简单,我们假设 JNI 或 VM 调用SetLastError()
自身并清除我们的最后一个错误。
我们不想放弃一对一的映射设计,那么我们能做些什么来解决这个难题呢?
这是一个在这种情况下无济于事的类似问题:CreateFile() 返回 INVALID_HANDLE_VALUE 但 GetLastError() is ERROR_SUCCESS