2009-08-12 9 views
0

OK. J'ai essayé de faire en sorte qu'un programme que j'ai écrit en Java puisse savoir si le bureau de Windows est verrouillé en utilisant JNI. J'ai réussi à faire fonctionner JNI, mais le code C que j'utilisais au début ne renvoyait pas la bonne réponse. J'ai un nouveau code (from here on SO), je l'ai un peu changé, mais j'ai des erreurs de lien. Lors de la liaison, j'obtiens deux références non définies, une pour OpenInputDesktop et une pour CloseDesktop. Ils font tous deux partie de user32.dll.MinGW ne semble pas lier contre user32

La commande que je utilise pour relier et créer ma DLL est:

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 

J'ai essayé d'ajouter le répertoire lib explicitement, ainsi que la bibliothèque, mais l'erreur est la même. Rien d'étonnant, puisque MinGW élargit ma commande à:

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 

Donc, si vous allez lire à travers tout ce désordre, vous verrez que c:/MinGW/lib (où libuser32.a est conservé) et -luser32 sont déjà là. Fondamentalement, cela devrait bien fonctionner.

C'est la même commande que j'utilisais auparavant sans -lwtsapi32 (depuis que j'utilisais l'API des services Terminal Server), et cela a fonctionné correctement, et j'ai trouvé les bibliothèques dont elle avait besoin. Maintenant, ce que j'ai changé dans le code que j'ai pris (la réponse de dan_g) était de supprimer les variables statiques, puisque je suis sur XP et que je n'ai pas besoin de me soucier de la compatibilité avec Win9x. Quand j'ai utilisé son code tel quel, j'ai eu la même erreur de base, incapable de lier par exemple GetProcAddress, même si c'est dans kernel32 qui est déjà dans la commande du linker. Je pense qu'il me manque une commande magique. Les fonctions dans le Win32API standard ne semblent pas vouloir se lier. Cela fait des années que j'ai utilisé C et MinGW. Je fais pas mal de choses que je n'ai pas faites auparavant.

Quelqu'un peut-il me diriger dans la bonne direction? OK, j'ai travaillé sur cela plus loin et je suis toujours coincé. Si je fais la source un petit programme C simple (pas de substance JNI), il ressemble à ceci:

#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 se fera un plaisir compiler et lier que, et les pistes exécutables. Si j'utilise les commandes que j'ai utilisées (modifiées pour refléter ce fichier), cela produit une DLL sans problème.

Répondre

1

J'ai compris le problème. Quand je compile mon code à mettre dans une DLL pour Java à utiliser par JNI, le fichier objet a ces deux listes lorsque j'utilise nm pour voir ce qui est dans le fichier d'objet:

 U _CloseDesktop 
    U _OpenInputDesktop 

Quand vient le temps de lien, ceux-ci ne sont pas trouvés, donc je reçois l'erreur de l'éditeur de liens. Quand je compilez le code sans tous les trucs JNI à une DLL (qui, évidemment, ne fonctionnera pas avec Java) les symboles ressemblent à ceci:

 U [email protected] 
    U [email protected] 

Comme vous pouvez le voir, lors de la compilation pour faire une DLL JNI, mon Les fonctions ne sont pas décorées avec le @n, qui est à l'origine de mon erreur de liaison. Est-ce que quelqu'un sait comment je peux résoudre ce problème?

Alors, quel était le problème?

Je ne windows.h y compris

Cela fait toute la différence. Peut-être que cela aidera quelqu'un d'autre.

Questions connexes