PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ Compile zwischen verschieden Windows Versionen


mekakic
2013-05-22, 15:42:54
Hi.

Ich verwende u.a. einige Calls wie GetThreadId(), die wie ich erst vor kurzem rausgefunden habe Windows XP ausschließen. Ich konnte den Code entsprechend auch unter Windows XP substituieren... das Problem ist eher der Build bzw. das ich beides unterstützen möchte, um ggf. den WinXP Teil auch irgendwann mal zu entfernen.

Ich habe nach einem #pragma Call gesucht, um hier abhängig von der Windows Version unterschiedlichen Code zu erzeugen. Irgendwie will es mir nicht gelingen nachdem ich lange mit WINVER & Co rumgespielt habe und das Problem ist (glaub ich), dass dies eher ein Laufzeit-Feature als ein Compile Feature ist. Jetzt frage ich mich, wie ich das zur Laufzeit machen kann? Muß ich WINVER nur setzen, wenn ich verhindern will, dass der Code hier compiliert?

Die Anwendung soll auf Win7 und Windows XP bauen und zur Laufzeit den für die Plattform korrekten Code ausführen... mit der Einschränkung dass ein Build auf einer XP Plattform nur den legacy Code reinbauen sollte:

#if WINVER >= 0x0502
if( windowsversion >= 0x0502 ) {
GetThreadId(...)
} else {
#endif
myGetThreadId(...)
#if WINVER >= 0x0502
}
#endif

Hat jemand eine Idee, wie man das macht? Ich bastel schon länger an seltsamen Konstrukten wie diesem herum, aber immer mit dem Gefühl, dass das doch einfacher gehen müsste?

Coda
2013-05-22, 16:22:24
Wie willst du bitte zur Compile-Time mit einem Macro, dass einfach nur unterschiedlichen Code für den Compiler erzeugt unterscheiden ob das Ding zur Laufzeit auf XP oder Vista läuft?

Natürlich funktioniert das nicht. Du musst zur Laufzeit die Version abfragen und dann die Funktion manuell über GetProcAdress aus der DLL laden:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724358(v=vs.85).aspx

Ich würde dir aber raten einfach immer myGetThreadId zu verwenden, wenn du XP wirklich noch unterstützen willst. Meiner Meinung nach ist es aber wirklich langsam an der Zeit es einfach zu ignorieren.

mekakic
2013-05-23, 11:15:01
Ich wollte damit je nur den Build unter XP hinkriegen, zusätzlich sollte es eine Laufzeitprüfung geben... es war eben der aktuelle Stand wo ich nicht weiter kam.

Eigentlich wird der XP Code abseits des Prototypen wohl auch nicht mehr gebraucht... da aber leider schon. So hab ich es jetzt gebaut und es scheint zu funktionieren!

Danke :)

Muß ich dafür zwingend die Version abfragen, oder würde es nicht reichen wenn GetProcAddress() einen nullptr zurückliefert um zu wissen, dass der Call unter der Plattform nicht zur Verfügung steht?

HMODULE module = GetModuleHandle( TEXT("Kernel32") );
typedef DWORD (WINAPI *GetThreadId_t)(HANDLE);

GetThreadId_t GetThreadId = (GetThreadId_t)GetProcAddress(module, "GetThreadId");
if( GetThreadId != nullptr ) {
DWORD threadId = GetThreadId(mainThread);
}

Gnafoo
2013-05-24, 22:15:58
Das müsste eigentlich reichen. Aber du solltest LoadLibrary/FreeLibrary anstatt GetModuleHandle verwenden. GetModuleHandle funktioniert nur, wenn das Modul bereits geladen ist. Das ist bei kernel32 zwar nahezu immer der Fall, aber wenn du mal etwas aus advapi32 oder so brauchst, dann funktioniert das so unter Umständen nicht mehr.

Da die Module einen Referenzzähler haben, schadet es auch nicht, ein Modul mit LoadLibrary zu laden, das bereits geladen ist.