行。我一直在努力创建一个用Java编写的程序,能够通过使用JNI来确定Windows桌面是否被锁定。我已经成功地让JNI正常工作,但我最初使用的C代码并未返回正确的答案。我得到了一些新代码(from here on SO),稍微修改了一下,但是我遇到了链接错误。
链接时,我得到两个未定义的引用,一个用于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 _DllMainCRTStartup@12 --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。
答案 0 :(得分:1)
我已经找到了问题所在。当我编译我的代码以放入JNI使用的Java DLL时,当我使用nm来查看目标文件中的内容时,目标文件有这两个列表:
U _CloseDesktop
U _OpenInputDesktop
到了链接的时候,找不到那些,所以我得到链接器错误。当我编译没有所有JNI内容的代码到DLL(显然不适用于Java)时,符号看起来像这样:
U _CloseDesktop@4
U _OpenInputDesktop@12
正如您所看到的,在编译生成JNI DLL时,我的函数没有被@n修饰,这就是导致链接错误的原因。有谁知道我怎么解决这个问题?
那是什么问题?
我没有包括windows.h
这一切都有所不同。也许这会帮助别人。