2009-08-12 81 views
0

好的。我一直在試圖編寫一個我一直用Java編寫的程序,能夠發現Windows桌面是否被使用JNI鎖定。我已經成功地獲得了JNI的工作,但是我最初使用的C代碼並沒有返回正確的答案。我得到了一些新的代碼(from here on SO),稍微改了一下,但我有鏈接錯誤。MinGW似乎沒有鏈接到user32

鏈接時,我獲得兩個未定義的引用,一個OpenInputDesktop,一到CloseDesktop。這些都是user32.dll的一部分。

我使用鏈接,並創建我的DLL的命令是:

c:/MinGW/bin/gcc -shared -o JNIHelper.dll 
        com_little_cute_display_helper_JNIHelper.o 
        -Wl,--add-stdcall-alias,--kill-at,--output-def,def_file 

我試着將明確lib目錄,以及圖書館,但錯誤是一樣的。這並不奇怪,因爲MinGW的擴展我的命令:

c:/MinGW/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe --shared -Bdynamic 
      -e [email protected] --enable-auto-image-base -o JNIHelper.dll 
      /mingw/lib/dllcrt2.o c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o 
      -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5 
      -Lc:/MinGW/bin/../lib/gcc -L/mingw/lib/gcc/mingw32/3.4.5 
      -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../../../mingw32/lib 
      -L/mingw/lib/gcc/mingw32/3.4.5/../../../../mingw32/lib 
      -L/mingw/lib -Lc:/MinGW/bin/../lib/gcc/mingw32/3.4.5/../../.. 
      -L/mingw/lib/gcc/mingw32/3.4.5/../../.. 
      com_little_cute_display_helper_JNIHelper.o 
      --add-stdcall-alias --kill-at --output-def def_file 
      -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 
      -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt 
      c:/MinGW/bin/../lib/gcc/mingw32/3.4.5/crtend.o 

所以,如果你通過所有那些亂七八糟的閱讀,你會看到C:/ MinGW的/ lib目錄(其中libuser32.a保管)和-luser32都已經在那裏。基本上,這應該連接好。

這是較早的,我只使用不-lwtsapi32(因爲我使用終端服務API)相同的命令,它工作得很好,然後,並且能夠找到其所需的庫。

現在我在我把代碼(dan_g的答案),改變的是取出靜態變量,因爲我在XP,不需要擔心Win9x的兼容性。當我按照原樣使用他的代碼時,我得到了相同的基本錯誤,例如,無法鏈接到GetProcAddress,即使它在已經在鏈接器命令中的kernel32中。

我想我錯過了一些神奇的命令。標準Win32API中的函數似乎並不想鏈接。自從使用C和MinGW以來,這已經有好幾年了。我做了很多事,我也沒做過。

有人能指出我正確的方向嗎?


好的,我一直在進一步研究,我仍然堅持。如果我做源簡單小C程序(沒有JNI東西),它看起來像這樣:

#define _WIN32_WINNT 0x0501 
#define WINVER 0x0501 
#include <windows.h> 
#include <windef.h> 
#include <winnt.h> 

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) { 

    HDESK hDesk = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED); 

    if (hDesk) { 
     CloseDesktop(hDesk); 

     printf("unlocked"); 
    } else { 
     printf("locked"); 
    } 
} 

的MinGW將愉快地編譯和鏈接,並運行可執行文件。如果我使用我一直使用的命令(改變爲反映這個文件),它會產生一個沒有問題的DLL。

回答

1

我已經想通了這個問題。當我編譯我的代碼放在一個DLL的Java通過JNI使用,對象文件有這兩個清單,當我用納米來看看有什麼目標文件中:

 U _CloseDesktop 
    U _OpenInputDesktop 

當談到時間鏈接,那些沒有找到,所以我得到鏈接器錯誤。當我沒有所有的JNI東西代碼編譯成一個DLL(這顯然不會使用Java工作)的符號是這樣的:

 U [email protected] 
    U [email protected] 

正如你可以看到,編譯做出JNI DLL時,我函數沒有用@n裝飾,這是什麼導致我的鏈接錯誤。有誰知道我該如何解決這個問題?

那麼究竟是什麼問題呢?

我不包括WINDOWS.H

這使所有的差異。也許這會幫助別人。