[C/Win32] libdwmapi.a vinden in x86-smaak

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
De titel zegt wel zo'n beetje genoeg: ik krijg het niet echt voor elkaar om de x86-versie van libdwmapi.a te vinden. Elke GCC-port levert alleen maar de x64-versie van deze library, want een tikkie vervelend is.

Wat ik tot nu toe heb geprobeerd:
  • Stiekem toch de x64-versie meegeven aan de linker. Dit levert 'undefined reference to foo' op.
  • De Microsoft-versies (dwmapi.lib) proberen. Het programma linkt wel, maar wil daarna niet starten. Dit is vaag, want MinGW ondersteunt officieel wel MSVC-libraries (.lib). Werkt blijkbaar niet altijd.
  • Met reimp/dlltool (http://code.google.com/p/lib2a/) geprobeerd de .lib (die uit de Windows SDK komt overigens) te converteren naar een .a-bestand. Het lijkt allemaal goed te gaan, maar nog steeds verwijzen de headers volgens de linker naar niet-bestaande functies.
  • Een rijtje GCC-ports afgezocht naar libdwmapi.a (x86). TDM-GCC heeft 'em niet, MinGW64 niet en MinGW(32) ook niet.
  • ...
Heeft iemand enig idee hoe ik die dingen verder zelf kan maken ofzo? Ik bedoel, de mensen bij TDM-GCC bijvoorbeeld moeten toch ook ergens mee beginnen (met dwmapi.lib bijvoorbeeld). :?

En ehm, voor de duidelijkheid: zonder -m32 (implies x64) compilen en zelf libdwmapi.a (x64) aanwijzen werkt perfect.

[ Voor 4% gewijzigd door Orwell op 06-05-2012 22:42 ]


Acties:
  • 0 Henk 'm!

  • 0xDEADBEEF
  • Registratie: December 2003
  • Niet online

"Religion is an insult to human dignity. With or without it you would have good people doing good things and evil people doing evil things. But for good people to do evil things, that takes religion." - Steven Weinberg


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Ik krijg exact dezelfde fouten met die library als met degene die met aanpak #3 zelf maak. En dat vind ik nou vreemd. Deze dus:

code:
1
2
obj/main.o:main.c:(.text+0x2520): undefined reference to `DwmIsCompositionEnabled'
obj/main.o:main.c:(.text+0x25a1): undefined reference to `DwmExtendFrameIntoClientArea'


Erg standaard dus voor 'je library deugt niet'. Hoe ik de linker gebruik:

Makefile:
1
gcc.exe <object files> <res file> -o "<output>" -L"<MinGW64\libmap>" -static-libgcc -mwindows lib/libdwmapi.a  -s -m32 -std=c99


Misschien zit hier wel de fout in, maar dat lijkt me sterk. Dit werkt namelijk altijd, alleen met toevallig libdwmapi.a (x86) dus niet. Als ik -m32 weglaat en libdwmapi.a door de meegeleverde x64-versie vervang, werkt het prog perfect.

Helaas, met deze lib dus niet.

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:51
Waar komen de declaraties van die functie vandaan? De linker error doet vermoeden dat ze met de verkeerde calling convention gedeclareerd zijn. Die functies gebruiken de stdcall conventie en dan zou de symbol _DwmIsCompositionEnabled@4 moeten heten (let op de leading underscore en de @4, waarbij 4 het aantal bytes dat als argumenten op de stack geplaatst wordt).

Als ik onder Linux test met dit programma:
C:
1
2
3
4
5
6
7
8
9
10
#include <windows.h>

HRESULT WINAPI DwmIsCompositionEnabled(BOOL *pfEnabled);

int main()
{
    BOOL x;
    DwmIsCompositionEnabled(&x);
    return 0;
}

Dan kan ik het met de door 0xDEADBEEF gelinkte library als volgt compileren:
i486-mingw32-gcc test.c libdwmapi.a

Zoiets moet onder Windows zelf met GCC natuurlijk ook lukken.

Haal ik de declaratie weg dan wordt de default calling conventie (cdecl) gebruikt en krijg ik een linker error: undefined reference to _DwmIsCompositionEnabled. Merk op dat daar wél een leading underscore bij staat. Dat is dus niet exact hetzelfde als in jouw situatie, hoewel de Windows port van binutils die leading underscores misschien zelf weghalen (wat dus niet handig is).

Je kunt met objdump de symbolen die geëxporteert worden door libdwmapi.a en geïmporteerd worden in je object files zien. Dan kun je snel genoeg zien wat de discrepantie is, lijkt me. Voorlopig ga ik er gewoon vanuit dat je dwmapi.h nergens include, of dat om een andere reden de functies niet gedeclareerd worden voordat je ze gebruikt.

[ Voor 33% gewijzigd door Soultaker op 07-05-2012 00:08 ]


Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Nou, ik heb dus inderdaad met objdump de fout gevonden. Wat bleek? De definitie in de dwmapi-headers en -libraries zijn het niet erg met elkaar eens. In de headers stond bijvoorbeeld:

C:
1
2
3
HRESULT DwmIsCompositionEnabled(
    BOOL *pfEnabled
);


... wat dus:

C:
1
2
3
HRESULT WINAPI DwmIsCompositionEnabled(
    BOOL *pfEnabled
);


.. moet zijn als je de Microsoft-standaard aanneemt. Zonder 'WINAPI' heeft de linker blijkbaar geen idee welke functie die die moet callen.

Nu vraag je je wellicht af waarom libdwmapi.a (x64) dan wel gewoon die foute header slikt. Dat heeft waarschijnlijk te maken met het feit dat die library cdecl gebruikt, dus bijvoorbeeld DwmIsCompositionEnabled (ja, inderdaad, zonder _) en dat die library WINAPI niet verwacht.

Nouja, de conclusie is dus ongeveer dat de beste mensen van TDM-GCC besloten hebben om de DWM-functies anders te declareren in de headers en libraries, en dat je daarom niet zomaar even libraries van andere compilers kan gebruiken. Vreemd.
Soultaker schreef op maandag 07 mei 2012 @ 00:02:
...

Voorlopig ga ik er gewoon vanuit dat je dwmapi.h nergens include, of dat om een andere reden de functies niet gedeclareerd worden voordat je ze gebruikt.
Zo dom ben ik nou ook weer niet. ;)

[ Voor 13% gewijzigd door Orwell op 07-05-2012 15:43 ]


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
Orwell schreef op maandag 07 mei 2012 @ 15:41:
In de headers stond bijvoorbeeld:
C:
1
2
3
HRESULT DwmIsCompositionEnabled(
    BOOL *pfEnabled
);

... wat dus:
C:
1
2
3
HRESULT WINAPI DwmIsCompositionEnabled(
    BOOL *pfEnabled
);

.. moet zijn als je de Microsoft-standaard aanneemt. Zonder 'WINAPI' heeft de linker blijkbaar geen idee welke functie die die moet callen.
't Is een macro voor __stdcall, en dus zijn de declaraties identiek als je met /Gz compileert.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein

Pagina: 1