Ressourcen entpacken



  • Martin Richter schrieb:

    @webfritzi:
    Warum castest Du hInstance? Das irritiert doch nur und ist Quelle für üble Fehler. Und wenn wäre höchstens ein static_cast hier erlaubt um diese Fehler zu vermeiden... 🕶

    Deswegen:

    codeworx schrieb:

    das mit hInst will immernochnicht (falsche typen hier, does not match da, usw. usf.).



  • codeworx schrieb:

    natürlich ist da ne schleife:

    while(!kbhit());

    Das Prog funzt wie es ist nicht bei mir.

    Ich weis auch garnicht ob ic hdie ressourcen richtig im resource script (die .rc) datei richtig deklariert habe, oder ob das was in der resource.h steht richtig ist...

    Ich will einfach nur nen kleinen resourcen entpacker, der die mitgelinkten ressourcen entpackt, mit möglichst wenig aufwand.

    mfg

    OMG! Ich rede von der Funktion die main-Funktion soll doch nur die Verwendung verdeutlichen! Dass das noch anzupassen ist, ist doch wohl klar.



  • Egal, CodeFinder. Du hast ihm nichts neues gegeben. Den Code hatte er doch (in etwa) auch schon.



  • Ne egal ist das nicht. Er soll ja auch verstehen, dass es mir um die Funktion ('ExtractReSrcFile') ging, nicht um die main 🙄 .



  • Ich denke, das war ihm klar. Mit seinem Statement wollte er nur ausdrücken, dass außer einer Endlosschleife da nicht viel passiert. Wie vorher halt auch schon.


  • Mod

    WebFritzi schrieb:

    Deswegen:

    codeworx schrieb:

    das mit hInst will immernochnicht (falsche typen hier, does not match da, usw. usf.).

    Und das glaubst Du?
    1. HMODULE==HINSTANCE siehe defines in windows.h. Der Code funktioniert bei mir ohne cast!
    2. Überflüssige casts sind immer ein Problem
    3. Jederr cast will sehr wohl überlegt sein.



  • Martin Richter schrieb:

    Und das glaubst Du?
    1. HMODULE==HINSTANCE siehe defines in windows.h.

    War zu faul nachzuschauen. 😉

    Martin Richter schrieb:

    2. Überflüssige casts sind immer ein Problem
    3. Jederr cast will sehr wohl überlegt sein.

    Mag so sein. Ich sehe es aber nicht so, weil ich noch nie (und damit meine ich auch NIE) Probleme mit Casts hatte. Ich verwende stets C-Casts.



  • ich mach das jetzt letzen endes so:

    #include <windows.h>
    #include "resource.h"

    int APIENTRY WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
    {
    LPVOID ldata = LockResource(LoadResource(0,FindResource(0,MAKEINTRESOURCE(ID_MOD_02),"BINARY")));

    //tu irgendwas (bspweise mit ldata irgendwas anfangen (entpacken, mit anderen funktionen abspielen, ...

    UnlockResource(ldata);
    return 0;
    }

    funzt 1a und bin glücklich, hat das denn so seine richtigkeit?

    mfg



  • Naja, du solltest schon auf Fehler prüfen. Und UnlockResource() brauchst du nicht in Win32.

    @Schlaue Leute: Wozu eigentlich das LockResource? Man kann doch auch das Handle von LoadResource nach LPVOID casten. Funzt doch auch.



  • WebFritzi schrieb:

    Martin Richter schrieb:

    2. Überflüssige casts sind immer ein Problem
    3. Jederr cast will sehr wohl überlegt sein.

    Mag so sein. Ich sehe es aber nicht so, weil ich noch nie (und damit meine ich auch NIE) Probleme mit Casts hatte. Ich verwende stets C-Casts.

    Das hat nix mit C oder C++ Casts zu tun: Da wo man ohne Casts auskommt, sollte man auch keine verwenden!


  • Mod

    codeworx schrieb:

    #include <windows.h>
    #include "resource.h"

    int APIENTRY WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow)
    {
    LPVOID ldata = LockResource(LoadResource(0,FindResource(0,MAKEINTRESOURCE(ID_MOD_02),"BINARY")));

    //tu irgendwas (bspweise mit ldata irgendwas anfangen (entpacken, mit anderen funktionen abspielen, ...

    UnlockResource(ldata);
    return 0;
    }

    funzt 1a und bin glücklich, hat das denn so seine richtigkeit?

    Nein! Ich würde immer das hInstance Handle übergeben! Weder LoadResource noch FindResource bekommen bei Dir das hInstance Handle!
    Dieser Code würde in einem DLL-Modul kläglichst versagen.


  • Mod

    WebFritzi schrieb:

    @Schlaue Leute: Wozu eigentlich das LockResource? Man kann doch auch das Handle von LoadResource nach LPVOID casten. Funzt doch auch.

    Erst LockResource mapped den entsprechenden Speicher ein. Wenn Du wenig Resourcen hast, sind die Seiten bereits im Speicher. Werden diese jedoch größer ist das nicht gewährleistet.



  • [quote="CodeFinder"]

    WebFritzi schrieb:

    Das hat nix mit C oder C++ Casts zu tun: Da wo man ohne Casts auskommt, sollte man auch keine verwenden!

    Ich hasse Dogmen! Also, wenn du mir das nicht begründen kannst, sehe ich das nicht ein.

    Martin Richter schrieb:

    WebFritzi schrieb:

    @Schlaue Leute: Wozu eigentlich das LockResource? Man kann doch auch das Handle von LoadResource nach LPVOID casten. Funzt doch auch.

    Erst LockResource mapped den entsprechenden Speicher ein. Wenn Du wenig Resourcen hast, sind die Seiten bereits im Speicher. Werden diese jedoch größer ist das nicht gewährleistet.

    Danke für die Aufklärung. Jetzt hab auch ich es kapiert.



  • WebFritzi schrieb:

    Also, wenn du mir das nicht begründen kannst, sehe ich das nicht ein.

    Ein paar einfache Gründe: Casts sind in vielen Fällen unnötig und blähen den Code übermäßig auf, wo es gar nicht nötig wäre. Zudem kann insbesondere der C-Cast, da er kontextsensitiv ist, je nach Fall ein static_cast, ein const_cast, ein reinterpret_cast oder gar mehrere zugleich sein - oft, obwohl man eigentlich nur einen static_cast oder implicit_cast wollte. => static_cast verwenden oder - wenn nicht nötig - gar nicht casten. Ein gutes C++-Programm sollte eigentlich mehrheitlich ohne Casts auskommen.

    In diesem speziellen Fall halte ich den Cast allerdings - sofern du ihn als static_cast schreibst 😉 - für vertretbar. Casten zwischen Handles ist, auch wenn es hier laut windows.h ausdrücklich nicht nötig ist, für gewöhnlich unerläßlich. Wer es nicht glaubt, definiere in den Compileroptionen mal das Präprozessorsymbol "STRICT". Und das hat auch fast immer seinen Grund - Handles sind wie Zeiger auf polymorphe Datentypen zu behandeln, und zwischen denen castet man ja auch nicht ohne weiteres herum.



  • @WebFritzi: Also böse gesagt ist das ja dann möglicherweise eher Dein Problem, wenn Du es nicht einsiehst (da Du ja dann später die Probleme bekommen könntest). Aber okay, das mal hier als Beispiel (wobei dieses Beispiel bewusst übertreibt):

    short __stdcall DlgProc(HINSTANCE hDlg, UINT uiMessage, unsigned short wParam, unsigned short lParam)
    {
       // ...
    }
    

    So, wie man sieht ist diese Dlg-Proc ist vollkommen falsch 😃 .
    Wenn Du diese dann aber so verwendest, sollte es keinen Compiler-Fehler geben:

    DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(DLG_MAIN), (DLGPROC)DlgProc);
    

  • Mod

    WebFritzi schrieb:

    Ich hasse Dogmen! Also, wenn du mir das nicht begründen kannst, sehe ich das nicht ein.

    Ein cast kaschiert die falsche Nutzung einer Variablen. Typenkonforme Verwendung erlaubt es dem Programmierer sich etwas mehr auf den Compiler zu verlassen.

    1. Also nehmen wir mal an, Du hast eine Variable von Typ1 und die castest überflüssiger Weise auch auf Typ1, dazu noch mit einem "verabscheuungswürdigen" C-cast, der einem Dampfhammer gleichkommt und Du änderst in der Eveolution Deines Programmes nun die Variable auf Typ2, dann wird der Compiler Dir nicht helfen können und Dein Programm wird evtl. übelst abrauchen.
    2. Ein C++ cast static_cast, dynamic_cast ist da weitaus intelligenter und wenn man schon castet vorzuziehen! Er schützt einen wenigstens gegen einige falsche Verwendungen!
    3. Es macht ein Programm unlesbar.
    4. Es irritiert. Ein weitere Progranmmierer wie ich aus Deinen Team, wird sich denken: "Warum castst er hier" oh muss ein Schweinecode Trick sein, bis er merkt, dass es ein noop ist.

    Just my 2 cents!



  • Sehe ich das richtig, dass ein C-Cast

    Typ1 a;
    Typ2 b = (Typ2)a;
    

    folgendes macht:

    Typ1 a;
    Typ2 b = *((Typ2*)&a);
    

    ??? Wenn ja, sehe ich nicht,w as daran verwerflich sein sollte, solange ich weiß, was im Speicher vor sich geht.



  • WebFritzi schrieb:

    Sehe ich das richtig, dass ein C-Cast folgendes macht:

    Nicht ganz. Wie ich bereits schrieb, tut er, je nach Kontext, das, was static_cast, reinterpret_cast oder const_cast machen:

    int i = 1;
    const char* s = "ein String";
    
    double f = (double) i; // entspricht static_cast <double> (i)
    int* pi = (int*) &f; // entspricht reinterpret_cast <int*> (&f)
    char* s2 = (char*) s; // entspricht const_cast <char*> (s)
    

    Mit dem C++-Cast ist es also möglich, eine bestimmte Cast-Art zu erzwingen, wodurch er wesentlich differenzierter eingesetzt werden kann - man sieht z.B. an der Verwendung eines reinterpret_cast zumeist, daß es sich um implementierungsabhängige Operationen handelt, am static_cast, daß eine gewöhnliche, recht harmlose Castoperation vorliegt und am const_cast, daß entweder der Programmierer Designfehler eingebaut oder mit solchen umzugehen hat.

    WebFritzi schrieb:

    Wenn ja, sehe ich nicht,w as daran verwerflich sein sollte, solange ich weiß, was im Speicher vor sich geht.

    Es ist genausowenig verwerflich, globale Variablen, öffentliche Member, Makros etc. zu verwenden, wenn man genau weiß, was vor sich geht. Das ändert nichts an der Tatsache, daß all diese Dinge, Casts und insbesondere C-Casts eingeschlossen, Code unübersichtlicher machen, die Wartung des Codes durch Dritte (oder durch dich selbst nach zu langer Zeit) erschweren, schwer auffindbare Fehler und Bugs hervorrufen, bei der Portierung eines Programmes unerklärlicherweise fehlschlagen.


  • Mod

    Ich kan dem was audacia geschrieben hat nur zu 100% zustimmen.

    Per Definition sind C casts in unserer Firma untersagt.



  • @audacia: Vielen Dank für deine ausführliche Erklärung. Entspricht dann

    Typ2 b = reinterpret_cast<Typ2>(a);
    

    dem hier:

    Typ2 b = *(Typ2*)&a;
    

    ???

    Und was ist das Verhalten von dynamic_cast in der Dprache der C-Casts?


Anmelden zum Antworten