ld: Linken mit User32.dll



  • oenone schrieb:

    Eigentlich musst du die User32-Lib von MinGW linken und nicht die aus C:\Windows. Die sollte unter C:\MinGW\lib liegen (libuser32.a oder ähnlich).

    Die Datei ist da, aber wie linke ich sie?

    -llibuser32 funktioniert nicht, -luser32 auch nicht.

    Und mingw hat keine user32.inc, deshalb muss ich ja die benötigten Funktionen selbst als extern deklarieren.



  • Assembler-Lerner schrieb:

    Die Datei ist da, aber wie linke ich sie?

    -llibuser32 funktioniert nicht, -luser32 auch nicht.

    Eigentlich genauso wie du es ursprünglich versucht hast: -LC:\MinGW\lib -lUser32

    Assembler-Lerner schrieb:

    Und mingw hat keine user32.inc, deshalb muss ich ja die benötigten Funktionen selbst als extern deklarieren.

    Die meisten C-Compiler fügen den _ an. Das dürfte bei den Win32-Funktionen auch der Fall sein, also musst du .extern _FunktionsName benutzen.



  • Leider besteht das Problem weiterhin.



  • Ohne Quellcode kann ich dir glaube ich nicht weiterhelfen.

    Ich hab es aber auch mal ausprobiert:

    hello.asm:

    .extern _MessageBoxA@16
    .extern _ExitProcess@4
    
    .section .data
        window_title:
            .ascii "Message box\0"
        window_message:
            .ascii "It works!!!\0"
    
    .section .text
        .globl _start
        _start:
    
            # displays a message box       
            push    $0x0
            push    $window_title
            push    $window_message
            push    $0x0
            call    _MessageBoxA@16
            movl    $0x0, %eax
    
            # exit
            push    $0x0
            call    _ExitProcess@4
    

    Dann assemblen und linken:

    as -o hello.o hello.asm
    ld -o hello.exe hello.o -LC:\MinGW\lib -luser32 -lkernel32
    hello.exe
    

    ... und eine MsgBox popt hoch mit dem Text.

    Funktioniert das bei dir auch so?



  • Ich habe das Beispiel auch kompiliert, und es funktionert auch bei mir.
    Dazu noch kurz eine Frage: Wie kann ich verhindern, dass, wenn ich das Programm starte, im Hintergrund ein Konsolenfenster aufpoppt? Beim gcc kann man das verhindern, wenn man beim Kompilieren "-mwindows" angibt. Aber wie kann man das beim Linken erzielen?

    Und noch eine Frage:
    Was genau sagen die Zahlen hinter den per .extern deklarierten Dateinamen?

    oenone schrieb:

    .extern _MessageBoxA@16
    .extern _ExitProcess@4
    

    Also das "@16" und das "@4"?

    Hat das was mit den Parametern zu tun, die die Funktion verlangt, also "ExitProcess" verlang als Parameter 4 Bytes, also einen Int?
    Hättest du vielleicht einen Link zur Gnu-Assembler-Dokumentation, wo das erklärt ist?



  • Probier mal "--subsystem windows", um das Konsolenfenster zu umgehen. Bei meinem Test kam übrigens keins, da ich die exe schon aus einem Konsolenfenster aufgerufen habe ^^'

    Du hast richtig geraten, die Zahl ist die Anzahl an Bytes. Das liegt nicht an GAS oder Assembler, sondern an der Win-API:
    http://msdn.microsoft.com/de-de/library/zxk0tw93.aspx

    (Siehe "Namensergänzungskonvention", da steht auch das mit dem "_")



  • Ok, und wenn eine Funktion keinen Parameter annimmt ( void ), dann "@0"?



  • Genau 🙂



  • Das Program ist trivial, es soll einfach nur das Clipboard leeren.

    .extern _OpenClipboard@4
    .extern _EmptyClipboard@0
    .extern _CloseClipboard@0
    .extern _ExitProcess@4
    
    .section .text
    .globl _start
    _start:
    	push $0
    	call _OpenClipboard@4
    	jz .error
    
    	call _EmptyClipboard@0
    	jz .error
    
    	call _CloseClipboard@0
    
    	push $0
    	call _ExitProcess@4
    
    .error:
    	push $1
    	call _ExitProcess@4
    

    Es lässt sich mittlerweile kompilieren, es scheint aber nicht zu funktioneren.

    Wenn ich einen Text in die Zwischenablage kopiere, und dann das Programm starte, so bleibt der Text in der Zwischenablage 😞

    Vielleicht könntest du mir ein weiteres mal helfen?



  • Ich habe meinen Fehler selbst gefunden: ich muss natürlich erstmal den Rückgabewert der Funktionen mit cmp überprüfen vor jz .

    cmp $0, %eax
    jz .error
    

    Aber Danke für deine sonstige Hilfe, oenone.


Anmelden zum Antworten