Search code examples
javacdlljava-native-interface

Why does GetLastError() block my method?


I'm trying to write some functions for creating a Windows message-only window for working with the clipboard. I know it's failing to create the window, but when I add the GetLastError() function call, the function never returns to Java. This is making it tricky to debug.

JNIEXPORT jlong JNICALL Java_com_mypackage_ClipboardHelper_initialize
    (JNIEnv *env, jclass obj, jstring arg) {

    WNDCLASSEXW wc;

    ZeroMemory(&wc, sizeof(wc));
    wc.cbSize = sizeof(wc);
    wc.lpszClassName = _CC_WNDCLASSNAME;
    wc.lpfnWndProc = WndProc;
    wc.hInstance = GetModuleHandleW(NULL);

    if (!RegisterClassExW(&wc)) {
        printf("failed to register window class\n");
    }

    gWindowHandle = CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
        _CC_WNDCLASSNAME,
        L"CC clipboard helper window",
        0, 0, 0, 0, 0,
        HWND_MESSAGE, NULL,
        GetModuleHandleW(NULL),
        NULL);

    if (!gWindowHandle) {
        printf("failed to create window\n");
        printf(GetLastError()); //this line causes function to never return
        printf("\n");
        fflush(stdout);
    }

    return gWindowHandle;
}

Solution

  • Your program is not able to continue because you passed an invalid pointer to printf. GetLastError returns a DWORD and it has been considered as a char* pointer by printf.

    You can change your code like this to display the last error code

    if (!gWindowHandle) {
        printf("failed to create window with error=%d\n",GetLastError());
        fflush(stdout);
    }
    

    Or if you want a human readable error message you can use the FormatMessage function as explained here in MSDN : Retrieving the Last-Error Code

    Also take care to call GetLastError just after the error happens because the last error code of your current thread can be replaced by another function. For instance in your sample code you call a printf before calling GetLastError. As we do not know the printf implementation, it can change the last error code.