Forum AmigaOne Zone https://forum.amigaone.pl/ |
|
Programowanie pod AmigaOS 3.1 - kilka pytań. https://forum.amigaone.pl/programowanie-f13/programowanie-pod-amigaos-3-1-kilka-pytan-t935-30.html |
Strona 3 z 4 |
Autor: | Hextreme [ sobota, 25 lut 2017, 21:54 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
tchomasz napisał(a): Poniżej załączam moje wypociny z podmianą tagów - nie będę wklejał bo niezły tasiemiec z tego wyjdzie. Powiązałem pozycję okna z rozdzielczością ekranu, oraz pozycję filerequestera z rozdzielczością okna. Teraz zacząłem dłubać przy obsłudze plików. Za pomocą funkcji Examine() wyciągam sobie rozmiar pliku. Czy da się zarezerwować obszar pamięci dla funkcji Read(), w którym mają być odczytane dane z pliku za pomocą tego wyciągniętego rozmiaru - mam nadzieję że nie zamotałem. Chodzi o to, żeby odczytując plik dane były zapisywane do bufora o wielkości identycznej jak wielkość pliku. Oczywiście. Rezerwujesz pamięć za pomocą funkcji biblioteki exec do alokacji pamięci, np.: AllocMem(), AllocVec(). Jako argument podaj rozmiar pliku, czyli wartość odpowiedniego pola ze struktury FileInfoBlock. Pamiętaj by zwolnić tą pamięć gdy nie jest już potrzebna za pomocą analogicznej funkcji do zwalniania pamięci: FreeMem(), FreeVec(). |
Autor: | tchomasz [ niedziela, 26 lut 2017, 00:27 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Napisałem coś takiego - dopisane do poprzedniego kodu. Kod: static int BadaniePliku(void); char *plik; int rozmiar; char *zawartosc; long read; Kod: static int BadaniePliku(void) { BPTR in, check; char ch; struct FileInfoBlock *fib; if (fib=AllocVec(sizeof(struct FileInfoBlock), MEMF_ANY)) { if (check = Lock(plik, SHARED_LOCK)) { printf("Plik %s zostal zablokowy dla innych.\n", plik); if(Examine(check, fib)) { rozmiar = fib->fib_Size; printf("Plik %s ma rozmiar %d bajtow.\n", plik, rozmiar); } else { PrintFault(IoErr(), "Examine"); FreeVec(fib); return 0; } UnLock(check); } else { PrintFault(IoErr(), plik); FreeVec(fib); return 0; } FreeVec(fib); } else { PrintFault(ERROR_NO_FREE_STORE, "AllocMem - Examine"); return 0; } if (in = Open(plik, MODE_OLDFILE)) //otwarcie pliku { if (zawartosc=AllocVec(rozmiar, MEMF_ANY)) { if ((read = Read(in, zawartosc, rozmiar))==-1) { PrintFault(IoErr(), "Blad odczytu"); FreeVec(zawartosc); Close(in); return 0; } else { printf("Ilosc przeczytanych bajtow %d\n", read); } FreeVec(zawartosc); } else { PrintFault(ERROR_NO_FREE_STORE, "AllocMem - open file"); Close(in); return 0; } } else { PrintFault(IoErr(), "Otwarcie pliku"); return 0; } Close(in); } Niby działa, ale mile widziane uwagi. |
Autor: | tchomasz [ środa, 1 mar 2017, 22:52 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Program mi wywala błąd. Załącznik: blad.png Poniżej część kodu - całość w załączniku poniżej. Wczytanie pliku mam powiązane z menu 'Open', zapis z 'Save as'. Przy zapisie tworzy mi plik o wybranej nazwie, zapisuje w nim 'zawartosc' i wywala błąd. O co mu chodzi? Kod: struct MenuItem *item=ItemAddress(menu, Code); if (Code==FULLMENUNUM(0, 0, NOSUB)) { FileReq(ASLHailRead, ASLOKTextRead); if (BadaniePliku()==NULL) { printf("Nie udalo sie wczytac pliku.\n"); } else { OpenFile(); } } if (Code==FULLMENUNUM(0, 3, NOSUB)) { FileReq(ASLHailWrite, ASLOKTextWrite); WriteFile(); } Kod: static int BadaniePliku(void)
{ BPTR check; struct FileInfoBlock *fib; if (fib=AllocVec(sizeof(struct FileInfoBlock), MEMF_PUBLIC)) { if (check = Lock(plik, SHARED_LOCK)) { printf("Plik %s zostal zablokowy dla innych.\n", plik); if(Examine(check, fib)) { rozmiar = fib->fib_Size; printf("Plik %s ma rozmiar %d bajtow.\n", plik, rozmiar); } else { PrintFault(IoErr(), "Examine"); FreeVec(fib); return 0; } UnLock(check); } else { PrintFault(IoErr(), plik); FreeVec(fib); return 0; } FreeVec(fib); } else { PrintFault(ERROR_NO_FREE_STORE, "AllocMem - Examine"); return 0; } } static int OpenFile(void) { BPTR in; if (in = Open(plik, MODE_OLDFILE)) //otwarcie pliku { if (zawartosc=AllocVec(rozmiar, MEMF_PUBLIC)) { if ((read = Read(in, zawartosc, rozmiar))==-1) { PrintFault(IoErr(), "Blad odczytu"); FreeVec(zawartosc); Close(in); return 0; } else { printf("Ilosc przeczytanych bajtow %d\n", read); } // FreeVec(zawartosc); } else { PrintFault(ERROR_NO_FREE_STORE, "AllocMem - open file"); Close(in); return 0; } } else { PrintFault(IoErr(), "Otwarcie pliku"); return 0; } Close(in); } static int WriteFile(void) { BPTR out; if (out = Open(plik, MODE_NEWFILE)) { if ((write = Write(out, zawartosc, rozmiar))==-1) { PrintFault(IoErr(), "Blad zapisu"); FreeVec(zawartosc); Close(out); return 0; } else { printf("Ilosc zapisanych bajtow %d\n", write); } FreeVec(zawartosc); } else { PrintFault(IoErr(), "Otwarcie pliku - zapisz jako"); return 0; } Close(out); } |
Autor: | Hextreme [ czwartek, 2 mar 2017, 00:45 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Przyjrzałem się załączonemu kodowi źródłowemu. Zauważyłem, że w funkcji zapisu WriteFile() nie rezerwujesz pamięci. Wskaźnik zawartość nie jest przypisany do żadnej zaalokowanej pamięci! A próbujesz zapisać w pliku część pamięci o rozmiarze rozmiar spod tego wskaźnika. Jest to nielegalne. Dodatkowo próbujesz zwolnić pamięć spod tego adresu za pomocą FreeVec() bez uprzedniej alokacji. Teraz pytanie: co chcesz w tym pliku zapisać? |
Autor: | tchomasz [ czwartek, 2 mar 2017, 10:33 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
To po kolei. Mam dwie funkcje OpenFile i WriteFile, obie są podpięte pod menu. Wszystkie testy robię na jednym przykładowym pliku. Klikając w menu Open wybieram mój przykładowy plik. Badam go funkcją BadaniePliku, aby ustalić jego wielkość i w funkcji OpenFile allokuję tyle pamięci co wielkość pliku. Później odczytuję plik i to co odczytam przechowuję w 'zawartosc'. Nie robię FreeVec(zawartosc) w OpenFile, po to aby to co odczytałem z pliku w kosmos mi nie poszło i żebym mógł w funkcji WriteFile z tego skorzystać. Klikając w menu Save as wybieram pod jaką nową nazwą ma być zapisany mój plik. Później 'zawartosc' kopiuję do tego pliku i wtedy mi wywala błąd. Generalnie chciałem na razie sobie przetestować otwarcie i odczyt pliku, a później bez jakiejkolwiek zmiany zapis do nowego pliku. Dlatego w funkcji WriteFile nie allokuję pamięci tylko chciałem skorzystać z zaalokowanej w funkcji OpenFile - czy tak można zrobić? |
Autor: | Hextreme [ czwartek, 2 mar 2017, 13:46 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
OK. Na początek ważna kwestia. Chcę wykluczyć jedną ewentualność. Strukturę FileInfoBlock warto zaalokować za pomocą funkcji AllocDosObject(DOS_FIB, NULL) z biblioteki dos. Nie wiem, czy o to chodzi, ale warto to poprawić. Zwalniasz za pomocą FreeDosObject(DOS_FIB, fib). Mam pytanie: jakiego używasz kompilatora? Ten numer "Software Failure" oznacza nielegalny dostęp do pamięci (możesz o tym poczytać w pliku załącznikowym exec/alerts.h). Może mieć to związek z kompilatorem. Nie zauważyłem znaku komentarza przy FreeVec() w funkcji OpenFile(). Teoretycznie Twój kod powinien zadziałać, kiedy wywołasz najpierw "Open", a później "Save". Jednakże konstrukcja Twojego programu jest niefortunna. W przypadku gdy np. użytkownik od razu wybierze "Save" program się wysypie z podanego w poprzednim poście powodu. Polecam zmienić funkcję WriteFile(), by pobierała jako parametr co ma zapisać i ile bajtów ma zapisać, np. tak: int WriteFile(char *zawartosc, long rozmiar); Zaś jeśli chodzi o funkcję BadaniePliku() i OpenFile(), to polecam zrobić tak:
EDIT: U mnie program działa, nie wysypuje się. Obstawiam kompilator. |
Autor: | tchomasz [ czwartek, 2 mar 2017, 22:01 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Hextreme napisał(a): EDIT: U mnie program działa, nie wysypuje się. Obstawiam kompilator. Ale kompilowałeś w nie zmienianej wersji? Ja używam gcc 2.95.3 - ze strony kas1e'a, którą podał swinkamor12 w innym wątku. Do tej pory mi wszystko działało. Testuję pod WinUAE. |
Autor: | Hextreme [ czwartek, 2 mar 2017, 22:58 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Gwoli ścisłości zmieniłem tylko jedną rzecz, która jednak nie odgrywa tutaj żadnej roli. Zmienną "write" uczyniłem lokalną. Nie wiem czemu, ale linker mi marudził. Poza tym nic w kodzie nie zmieniałem. Użyłem kompilatora DICE. |
Autor: | tchomasz [ piątek, 3 mar 2017, 22:13 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Jak możesz to wklej skompilowany program, to zobaczę czy pod WinUAE mi się wysypie. |
Autor: | Hextreme [ piątek, 3 mar 2017, 23:46 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Proszę. Do kodu musiałem tylko załączyć <exec/memory.h> bo nie rozpoznawał symbolu MEMF_PUBLIC. Czy na pewno wersja kodu, którą wkleiłeś jest najbardziej aktualna? |
Autor: | swinkamor12 [ sobota, 4 mar 2017, 06:55 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Parę poprawek: 1. Zmienne read i write jak Robert pisał warto zrobić jako lokalne 2. Brakowało otwarcia i zamknięcia utility library 3. Przy otwarciu okna lepiej nie podawać maksymalnych wymiarów jak są nie używane usunięte: WA_MaxWidth, -1, WA_MaxHeight, -1, 4. zmienna plik - to jest wskaźnik, pamięć po wywołaniu FreeAslRequest może zostać zwolniona i będą tam śmiecie trzeba przepisać zawartość. Warto też pobrać katalog - będzie można obsługiwać pliki też spoza aktulanego katalogu. char plik[1000]; memset(plik,0,sizeof(plik)); strncpy(plik,fr->rf_Dir, sizeof(plik)-1 ); AddPart( plik, fr->rf_File, sizeof(plik)-1 ); |
Autor: | tchomasz [ sobota, 4 mar 2017, 17:27 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Hextreme napisał(a): Proszę. Do kodu musiałem tylko załączyć <exec/memory.h> bo nie rozpoznawał symbolu MEMF_PUBLIC. Czy na pewno wersja kodu, którą wkleiłeś jest najbardziej aktualna? Działa bez problemu. Wysłane z mojego GT-I9300 przy użyciu Tapatalka |
Autor: | tchomasz [ sobota, 4 mar 2017, 17:30 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
swinkamor12 napisał(a): Parę poprawek: 1. Zmienne read i write jak Robert pisał warto zrobić jako lokalne 2. Brakowało otwarcia i zamknięcia utility library 3. Przy otwarciu okna lepiej nie podawać maksymalnych wymiarów jak są nie używane usunięte: WA_MaxWidth, -1, WA_MaxHeight, -1, 4. zmienna plik - to jest wskaźnik, pamięć po wywołaniu FreeAslRequest może zostać zwolniona i będą tam śmiecie trzeba przepisać zawartość. Warto też pobrać katalog - będzie można obsługiwać pliki też spoza aktulanego katalogu. char plik[1000]; memset(plik,0,sizeof(plik)); strncpy(plik,fr->rf_Dir, sizeof(plik)-1 ); AddPart( plik, fr->rf_File, sizeof(plik)-1 ); Dzieki za uwagi. W wolnej chwili porobię poprawki. Wysłane z mojego GT-I9300 przy użyciu Tapatalka |
Autor: | tchomasz [ niedziela, 5 mar 2017, 02:45 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Wystarczyło, że tylko zmienne read i write zmieniłem na lokalne i przestało się wywalać. utility.library dopisane, WA_MAX wywalone, zmiennej plik jeszcze nie ruszałem. |
Autor: | tchomasz [ sobota, 28 paź 2017, 23:42 ] |
Tytuł: | Re: Programowanie pod AmigaOS 3.1 - kilka pytań. |
Odkopuję trochę temat. Jak pobrać z systemu aktualną godzinę i datę? |
Strona 3 z 4 | Strefa czasowa: UTC + 1 |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |