Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++, WinAPI] Problem z zapisaniem zasobu do pliku

Ostatnio zmodyfikowano 2013-07-26 07:14
Autor Wiadomość
kris5665
Temat założony przez niniejszego użytkownika
[C++, WinAPI] Problem z zapisaniem zasobu do pliku
» 2013-07-25 08:46:00
Chcę aby mój program zapisywał zasób do pliku. Przeczytałem poradnik o zasobach (» Kurs WinAPI, C++ » PodstawyZasoby lekcja), zrobiłem wszystko tak jak jest napisane i skopiowałem kod z działu "Zapisywanie zasobu do pliku", bo akurat nie potrafie sam czegoś takiego napisać. Jednak pojawiają się błędy przy kompilacji, a że nie wiem o co chodzi w WinAPI i nie znalazłem nic ciekawego w internecie to nie daje rady tego naprawić. Nie chcę studiować całego WinAPI dla tego kawałka kodu, bo więcej nie będę z tego korzystać. Z góry dzięki za pomoc!

Kod:
C/C++
void wypakowanie()
{
    HINSTANCE hInstance;
    HRSRC hrsrc;
   
    HRSRC hLogo = FindResource( hInstance, MAKEINTRESOURCE( TITLE ), RT_RCDATA );
    if( hrsrc != NULL )
    {
        HGLOBAL pLogo = LoadResource( hInstance, hLogo );
        DWORD dwDlugosc = SizeofResource( hInstance, hLogo );
       
        HANDLE hPlik = CreateFile( "title.png", GENERIC_WRITE, NULL, NULL, CREATE_NEW,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL );
       
        DWORD dwBajtyZapisane;
       
        if( !WriteFile( hPlik, pLogo, dwDlugosc, dwBajtyZapisane, NULL ) )
             koniec();
       
        if( dwBajtyZapisane != dwDlugosc )
             koniec();
       
        CloseHandle( hPlik );
       
    }
    else
         koniec();
   
}

Log:

warning: passing NULL to non-pointer argument 3 of 'void* CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE)' [-Wconversion-null]|
error: invalid conversion from 'DWORD {aka long unsigned int}' to 'PDWORD {aka long unsigned int*}' [-fpermissive]|
error:   initializing argument 4 of 'BOOL WriteFile(HANDLE, PCVOID, DWORD, PDWORD, LPOVERLAPPED)' [-fpermissive]|

Dodam jeszcze że używam CodeBlocks
P-88728
Szadziu
» 2013-07-25 10:53:05
w funkcji WriteFile( hPlik, pLogo, dwDlugosc, dwBajtyZapisane, NULL ) za 4 argument podajesz DWORD zamiast PDWORD spróbuj może & dwBajtyZapisane. Ogólnie chodzi o to ze DWORD to long unsigned int a PDWORD to wskaznik na long unsigned int.
P-88731
Monika90
» 2013-07-25 15:21:24
Opróćz tego, co napisał Szadziu, to jeszcze zmienna hInstance jest niezainicjalizowana. Jej wartością ma być uchwyt do modułu, z którego chcesz załadować zasób. Może być NULL, co oznacza plik exe z głównym programem.

Poza tym, trzeci argument CreateFile jest typu DWORD, a nie typu wskaźnikowego. Nie należy używać NULL, tam gdzie powinno się używać liczby całkowitej, nawet jeśli przypadkiem to działa w tej czy innej implementacji.
P-88755
kris5665
Temat założony przez niniejszego użytkownika
» 2013-07-25 21:40:01
Wybaczcie ale jestem zielony jeżeli chodzi o te uchwyty :(. Mógłby ktoś napisać zmienić mi kod i wkleić, albo napisać poprawki?

Edit: Dzięki Szadziu, program sie kompiluje z tym wskaźnikiem, tylko że plik który sie zapisuje jest pusty, ma zero bajtów. Poniżej log (są jakieś ostrzeżenia, ale nie za bardzo wiem o co chodzi):


warning: passing NULL to non-pointer argument 3 of 'void* CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE)' [-Wconversion-null]
warning: 'hInstance' is used uninitialized in this function [-Wuninitialized]|
warning: 'hrsrc' is used uninitialized in this function [-Wuninitialized]|
P-88790
Szadziu
» 2013-07-25 23:22:27
warning: passing NULL to non-pointer argument 3 of 'void* CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE)' [-Wconversion-null]

przekazujesz null do 3 argumentu funkcji CreateFile  tutaj CreateFile( "title.png", GENERIC_WRITE, NULL, NULL, CREATE_NEW,
Przeczytaj o tej funkcji tu i przekaz co innego:
http://msdn.microsoft.com​/en-us/library/windows/desktop​/aa363858(v=vs.85).aspx

warning: 'hInstance' is used uninitialized in this function [-Wuninitialized]|
warning: 'hrsrc' is used uninitialized in this function [-Wuninitialized]|

Mówi o tym że używasz zmiennych hInstance i hrscr nie nadając im żadnych wartości. Co oznacza że przekazujesz je do jakiejś funkcji wraz z śmieciami które tam zawsze są na początku.

P-88804
Admixior
» 2013-07-26 01:13:28
Skoro nie rozumiesz uchwytów i nie chcesz się zagłębiać w winapi (tak jak pisałęś w 1 poście) to czemu nie zapiszesz za pomocą zwykłego ofstream:
C/C++
#define zaladuj(x,data_type) (const char*)(LockResource(LoadResource(0,FindResource(0,MAKEINTRESOURCE(x),data_type))))
#define rozmiar(x,data_type) SizeofResource(0,FindResource(0,MAKEINTRESOURCE(x),data_type))

int fun()
{
    ofstream plik( "blabla.bla", ios::out | ios::bin );
    if( plik.bad() )
    {
        //error
    }
    plik.write( zaladuj( id, typ ), rozmiar( id, typ ) ); //komentarz niżej
    plik.close();
}

id - pewnie wiesz co to jest
typ - jest to "id" odgórnie zdefiniowanego typu (nazwy "folderu" w zasobach) lub ciąg znaków char*/wchar_t* który jest nazwą  tego "folderu".

przykład:
zaladuj( RSC_IMG_BACKGROUND, L"PNG");   //lub bez 'L' (samo "PNG") w zależności od domyślnego ustawienia unicode
zaladuj( TITLE, RT_RCDATA );

Mam nadzieję że nie chcesz wypakowywać malwara z zasobów aplikacji jako dodatek do zwykłego programu.
P-88810
kris5665
Temat założony przez niniejszego użytkownika
» 2013-07-26 07:14:51
Oczywiście że nie :) Tak na prawde chcę zrobić gre bez mozliwosci edycji grafiki tzn. przy starcie aplikacja wypakowuje pliki do folderu, a na końcu je kasuje. Niby bardziej obyty użytkowników może to ominąć np. Resource Hackerem, ale sądzę że to zabezpieczenie jest w porządku.

Dzięki za kod, spróbuje się pobawić ofstreamem

Edit: Wszystko działa, dzięki wielkie dla Admixiora i dla wszystkich, którzy pomagali! W tamtym kodzie z ofstream był błąd, a mianowicie ios::binary zamiast ios::bin.
P-88813
« 1 »
  Strona 1 z 1