views:

569

answers:

1

OK. I've been trying to make a program I've been writing in Java be able to find out if the Windows desktop is locked by using JNI. I've succeed in getting JNI working, but the C code I was using at first wasn't returning the correct answer. I got some new code (from here on SO), changed it a little, but I'm having link errors.

When linking, I'm getting two undefined references, one to OpenInputDesktop, and one to CloseDesktop. These are both part of user32.dll.

The command I'm using to link and create my DLL is:

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

I've tried adding the lib directory explicitly, as well as the library, but the error is the same. This isn't surprising, since MinGW expands my command to:

 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

So if you go read through all that mess, you'll see that c:/MinGW/lib (where libuser32.a is kept) and -luser32 are both already in there. Basically, this should link fine.

This is the same command I was using earlier only without -lwtsapi32 (since I was using the Terminal Services API), and it worked fine then, and was able to find the libraries it needs.

Now what I changed in the code I took (dan_g's answer) was to take out the static variables, since I'm on XP and don't need to worry about Win9x compatibility. When I used his code as is, I got the same basic error, unable to link against GetProcAddress, for example, even though that's in kernel32 which is already in the linker command.

I'm thinking I'm missing some magic command. Functions in the standard Win32API don't seem to want to link in. It's been years since I used C and MinGW. I'm doing quite a bit I haven't done before too.

Can someone point me in the right direction?


OK, I've been working on this further and I'm still stuck. If I make the source a simple little C program (no JNI stuff), it looks like this:

#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 will happily compile and link that, and the executable runs. If I use the commands I've been using (changed to reflect this file), it produces a DLL without a problem.

+1  A: 

I've figured out the problem. When I compile my code to put in a DLL for Java to use by JNI, the object file has these two listings when I use nm to see what's in the object file:

     U _CloseDesktop
     U _OpenInputDesktop

When it comes time to link, those aren't found so I get the linker error. When I compile the code without all the JNI stuff to a DLL (which obviously won't work with Java) the symbols look like this:

     U _CloseDesktop@4
     U _OpenInputDesktop@12

As you can see, when compiling to make a JNI DLL, my functions aren't getting decorated with the @n, which is what's causing my linking error. Does anyone know how I can fix this?

So what was the problem?

I wasn't including windows.h

That made all the difference. Maybe this will help someone else.

MBCook