Problem beim Kompilieren von C-Code



  • Hallo ihr lieben,
    vorweg zu sagen: ich bin eine pfeife in C, HABE gegoogelt etc, und programmiere eig. nur in java.
    Nun habe ich ein programm geschrieben(java), dass aber auf hotkeys unter windows hören soll.
    Sicherlich werden viele wissen: java's listener funzen nur wenn ein java-fenster, frame etc. aktiv.
    nun hat ein herr unter
    http://www.softk.de/opensource/jglobalkeylistener.html
    (quellcode gibts dort auch)
    ein projekt, mit dem java auch hotkey abhören kann, die unter windows gedrückt werden, dazu lädt man in java eine DLL.
    Dazu muss jedoch ein C-Code kompiliert werden (eben als diese DLL)
    Ich habe mir quincy, CH, dev-C++ und cygwin gezogen, und versucht den code zu kompilieren.
    nachdem ich einige probleme behoben habe (zb. jni.h wurde nicht gefunden, habe ich den C-Code abgeändert, sodass jni.h mit vollem pfad gefunden wird.)
    liefert mir Dev-C++ folgendes:

    In function \_mingw\_CRTStartup': [Linker error] undefined reference to_dyn_tls_init_callback'
    [Linker error] undefined reference to \_cpu\_features_init' [Linker error] undefined reference toWinMain@16'
    Id returnes 1 exit status

    Info: ich hab nen win7 pro x64, java x64, eclipse x64.
    und hätte gerne dass diese DLL so kompiliert wird, dass es unter x64 und x86 läuft.

    Hat vllt jmd den Nerv mir das zu erklären?
    google ich diese fehlermeldungen, so komme ich zu mehreren ergebnissen, leider tauchen bei anderen compilern andere probleme auf... -,-



  • Wieso willst du die dort vorhandene, fertig compilierte "GlobalKeyLogger.dll" nochmal selbst compilieren?



  • Vielen Dank für die erste Antwort 😉
    nun ja wenn ich diese .dll per Befehl laden will, wie der Herr es beschreibt:

    try {
    	            System.loadLibrary("GlobalKeyLogger");
    	          }
    	          catch (UnsatisfiedLinkError ule) {
    	            System.load("C:\\Users\\Schnepma\\desktop\\GlobalKeyLogger.dll");
    	          }
    

    bekomm eich folgende fehler:

    Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\SchnepMa\Desktop\GlobalKeyLogger.dll: Can't load IA 32-bit .dll on a AMD 64-bit platform
    	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    	at java.lang.ClassLoader.loadLibrary1(Unknown Source)
    	at java.lang.ClassLoader.loadLibrary0(Unknown Source)
    	at java.lang.ClassLoader.loadLibrary(Unknown Source)
    	at java.lang.Runtime.load0(Unknown Source)
    	at java.lang.System.load(Unknown Source)
    	at test.<init>(test.java:52)
    	at test.main(test.java:331)
    

    Und der Author sagte, ich müsse die .dll, also den C-Code neu kompilieren, ich sollte die "C-profis" fragen.



  • Einfache Lösung: benutz eine 32-bit jvm



  • mac21 schrieb:

    In function \_mingw\_CRTStartup': [Linker error] undefined reference to_dyn_tls_init_callback'
    [Linker error] undefined reference to \_cpu\_features_init' [Linker error] undefined reference toWinMain@16'
    Id returnes 1 exit status

    Zumindest die letzte Fehlermeldung lässt darauf schließen, dass du als Projekttyp irgendsowas wie "Windows-Anwendung" eingestellt hast. Du willst aber eine DLL bauen.
    Die anderen beiden Fehler sehen komisch aus, dazu müsste man sich mit MingW auskennen, um dazu was zu sagen. Kannst ja mal nach _dyn_tls_init_callback googeln, vielleicht kommt dir was bekannt vor.



  • Ich habe mal eine 64Bit Variante der DLL compiliert (für die ich ein paar Umbauten vornehmen musste)

    http://www.file-upload.net/download-7874220/GlobalKeyLogger.dll.html

    Irgendwelchen weiteren Support übernehme ich aber natürlich nicht.



  • Vielen Dank an euch alle, ich kenne die forenregeln, die nettiquette etc.
    tut mir leid so einen aufwand zu machen.

    ich hätte jedoch noch 2-3 dinge:
    1. gary1195:
    wenn ich eine 32bit-dll kompiliere geht die auch unter 64bit?
    hat es einen vorteil eine "64bit dll" zu benutzen? geschwindkeit etc.? (also falls die DLL "richtigen" inhalt hätte, nicht nur den kurzen P-code in diesem beispiel
    2. Bashar:
    ich habe leider NULL ahnung und auch fand ich nicht viele einstellungen unter zB GCC (da ich es ja per CMD ausführe, weiß ich nicht wie ich "einstelle" ob exe, dll etc. rauskommen soll
    3. Wutz:
    SUPER! vielen dank, habs eben in java eingebunden, klappt einwandfrei!
    hierzu: wärst du so lieb und würdest das noch einmal in einer 32bit machen? dann hab ich beide, lasse das java-programm die architektur auslesen und verwende die entsprechende dll

    info: das ganze ist nur sone spielerei, die uns aber auch arbeit abnimmt 😉
    support ist nicht nötig, habt mir sehr viel geholfen

    und dann halte ich auch die klappe 😉



  • @Wutz:
    ahm tut mir leid...
    daheim, wo ich alle dateien des projekts in einen ordner schmeiße, hauts super hin.
    nun am anderen pc folgendes:
    einbinden der .dll:

    try {
              System.loadLibrary("GlobalKeyLogger");
            }
            catch (UnsatisfiedLinkError ule) {
              System.load("C:\\GlobalKeyLogger.dll");
            }
    

    dann gibt mir eclipse:

    Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\GlobalKeyLogger.dll: Can't find dependent libraries
    	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    	at java.lang.ClassLoader.loadLibrary1(Unknown Source)
    	at java.lang.ClassLoader.loadLibrary0(Unknown Source)
    	at java.lang.ClassLoader.loadLibrary(Unknown Source)
    	at java.lang.Runtime.load0(Unknown Source)
    	at java.lang.System.load(Unknown Source)
    	at cmdLine.<clinit>(cmdLine.java:43)
    

    hinweis: zeile 43 ist System.load("C:\\GlobalKeyLogger.dll");

    Das gibs doch nich 😞



  • Uhm okay, liegt wohl doch an der dll.

    System.load("C:/Windows/System32/amstream.dll");
    

    haut hin

    System.load("C:/Windows/System32/GlobalKeyLogger.dll");
    

    jedoch nicht...



  • mac21 schrieb:

    1. gary1195:
    wenn ich eine 32bit-dll kompiliere geht die auch unter 64bit?
    hat es einen vorteil eine "64bit dll" zu benutzen? geschwindkeit etc.? (also falls die DLL "richtigen" inhalt hätte, nicht nur den kurzen P-code in diesem beispiel

    Nein! die DLL und die JVM müssen die gleiche bittigkeit haben.
    Mir ist leider keine standard Möglichkeit bekannt die bittigkeit der jvm zu ermitteln, so dass du nicht einfach zwei DLLs haben kannst und dann die passende lädst. Du musst dann eben die DLLs durchprobieren.
    In einer 64-bit dll sehe ich keinen direkten vorteil es hängt eben von deinem Programm ab, 64-bit haben natürlich den Vorteil des größeren Speicherbereichs.



  • uhm okay dann würde ich das über ein

    try{ System.load("64bit.dll"); 
       }catch(Exception e){ 
                           irgendeine ausgabe;
                            try{ System.load("32bit.dll");}
                                }catch(Exeption e2){ andere ausgabe}
       }
    

    Also frag ich ab ob einer fehler auftrat etc.

    Aber nun is noch das problem, dass die dll nicht erkannt wird.
    habe GCC benutzt, um den Code selbst zu kompilieren (endlich fand ich ne schritt für schritt anleitung für dummies) http://cygwin.com/cygwin-ug-net/dll.html

    bei

    Then link to your dll with a command like:

    gcc -o myprog myprog.c -L./ -lmydll

    kriege ich leider

    c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../../mingw32/bin/ld.exe: cannot find -lmydll
    collect2: ld gab 1 als Ende-Status zurück

    und da andere dlls geladen werden können von java, liegt der fehler wohl an meiner dll

    also probeirte ich
    gcc -o myprog myprog.c -L./[/quote] ohne -lmydll

    -->

    C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to `WinMain@16'
    collect2: ld gab 1 als Ende-Status zurück
    

    Gibt es hier irgendjemanden der (zb Wutz 😉 ) den code umschreiben/optimieren kann?

    langsam verzweifle ich dran...



  • hast du das so eingetippt?
    Wenn deine Datei nicht libmydll.dll (oder so ähnlich, kenne mich bei windows nicht aus) dann macht das auch keinen Sinn.
    Ist dir klar, was

    -lmydll
    

    macht?
    Das linkt eine datei dazu (-l), diese wird in den Standard-Library-Verzeichnissen (auch das aktuelle Verzeichnis, da du

    -L./
    

    angegeben hast) gesucht und müsste von der form her etwa LIBmydll.dll sein.
    (lib klein, ist nur zur Verdeutlichung groß)



  • hallo Hyde,
    ah das berühmt berüchtigte L-Flag?
    also kann ich das weglassen, denn nach

    Then, tell gcc that it is building a shared library:

    gcc -shared -o mydll.dll mydll.o

    (also mit
    gcc -shared -o GlobalKeyLogger.dll GlobalKeyLogger.o )
    wurde eine .dll erzeugt, ohne fehler von GCC.
    somit dachte ich, ich sei fertig.

    So ging ich vor:
    - ich kopierte die beiden Dateien (die .c und die .h) in meinen Userordner, damit GCC die gleich findet.

    - Meine cmd-Eingabe:
    gcc -c GlobalKeyLogger.c
    brauchte keine fehler, die .o-Datei wurde erstellt

    - gcc -shared -o GlobalKeyLogger.dll GlobalKeyLogger.o
    ebenfalls keine fehler, die .dll wurde erstellt

    - dann dachte ich, dass gcc -o myprog myprog.c -L./ -lmydll
    noch wichtig sei, jedoch ohne dieses include-flag
    also: gcc -o GlobalKeyLogger GlobalKeyLogger.c
    ergabt

    c:/mingw/bin/../lib/gcc/mingw32/4.6.2/../../../libmingw32.a(main.o): In function `main':
    C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to `WinMain@16'
    collect2: ld gab 1 als Ende-Status zurück
    


  • Das Verhalten, dass du beschreibst, ist eigentlich das erwartete.
    Wenn die dll nicht gefunden wird, kannst du trotzdem kompilieren, nur nicht linken.
    Deshalb funktioniert auch

    gcc -c GlobalKeylogger.c
    

    Du beschreibst aber einen (denke ich) Windows-spezifischen Fehler, da keine WinMain definiert wurde. Damit kenne ich mich nicht aus.

    Davon aber abgesehen: Das ist das Vorgehen, um eine ausführbare Datei zu erhalten. Wenn ich dich richtig verstehe, möchtest du das doch gar nicht. Du wolltest doch nur die dll erstellen, um diese in Java zu laden.
    Damit solltest du doch am Ziel sein?



  • Okay, das verstehe ich. die dll wurde ja erstellt, also sollte das soweit hinhauen.
    nur kann ich eben diese DLL nicht einbinden...
    also muss diese kaputt/fehlerhaft sein.
    dlls aus dem windowsordner (testweise) kann ich einbinden
    z.B .

    System.load("C:\\Windows\\System32\\amstream.dll");
    

    das geht, nur bei meiner datei (egal ob die von wutz oder von mir kompiliert :

    Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: C:\GlobalKeyLogger.dll
           at java.lang.ClassLoader.loadLibrary(Unknown Source)
           at java.lang.Runtime.load0(Unknown Source)
           at java.lang.System.load(Unknown Source)
           at cmdLine.<clinit>(cmdLine.java:43)
    

    also doch was mit verlinken...


Log in to reply