C++ könyvtár segítség kérés

Fórumok

Nem boldogulok egy könyvtárral. Működik szépen, csak nem ganyézik ki maga után. Miután használtam, 10k rammal kevesebb lesz. https://github.com/emelianov/untarArduino Csak globálisnak tudom tenni, függvényen belül létrehozva crash. Ez nekem még mélyvíz. Előre is köszönöm ha valaki belenéz.

Hozzászólások

Szerkesztve: 2024. 01. 24., sze – 12:26

.

Probalhatnal esetleg a szerzojenek irni.

Ebben a példában például a FILE objektum nincsen lezárva: https://github.com/emelianov/untarArduino/blob/master/examples/Extract-…

Ennek nincsen close párja: File f = SPIFFS.open(...

Megnéztem a libben sincsen. Ezen kívül még azt nézném meg, hogy az állapotgép az extract-ban lezárja-e a létrehozott FILE típusú objektumokat.

Maga a lib (ami 1 db header) kicsivel több mint 512 bájtot foglal IMHO, mivel ekkora buffert allokál.

Mire jó ez egyébként, mi a célod vele?

Valgrind a barátod. (Most azt hadd ne kérdezzem meg, hogy template-ek minek kellenek bele. (Akármik is legyenek azok.))

Azzal az a baj, hogy ertelmes lib kozvetlen regisztereket fog irni (mert pl. a digitalWrite-nal joval gyorsabb), akar ASM betetek is lehetnek benne. Ami azt jelenti, hogy Linuxon ezeket is implementalnod kell. Plusz lehet, hogy a hardware-t is (egyszerubb esetben a periferiakat, rosszabb esetben meg amiket radugsz). Ugye ha a radugott nyomogomb/UART/SPI-os eszkoz alapjan mesz ra egy kodreszre, akkor azzal is kell valamit kezdened.

Szoval nem tunik egyszerunek.

A strange game. The only winning move is not to play. How about a nice game of chess?

Szerkesztve: 2024. 01. 24., sze – 13:15

A pathprefix mallocjához nincs free. A fullpath-ra se hívja meg minden esetben a free-t az extract(), ilyen esetekben az f->close is kimarad.

Ezt nem is tudom, hogyan kellene, hiszen időnként a "" literált rakja a pathprefix-be, máskor meg a malloc eredményét. Asszem ez re lesz faktorálva.

Destruktor van ebben az ArduinoC++-ban? Mert az untar.h-ban nem látok.

Szerk: ez lett https://github.com/lzsiga/untarArduino/commit/5d8b9d15fe6342bfbf5e0baa7…

(Work In Progress)

		if (f != NULL) {
			#ifndef TAR_SILENT
			INTDBG Serial.println();
			#endif
			f->close();
Serial.println(F("\nFree RAM: ") + String(ESP.getFreeHeap()) + F(" Bytes, ") + String(ESP.getHeapFragmentation()) + F("% fragmentation"));
			f = NULL;
		}
		_state = TAR_DONE;
		#ifdef TAR_CALLBACK
		if (cbEof != NULL)
			cbEof();
		#endif
		bytes_read = 0;
	}

Az extract függvényben itt látszik, ahogy fogy a ram. Nincs ötletem, ennyire még nem vagyok profi C++

Ez azért van tele malloc-okkal, mert eredetileg C-ben volt? C++-ban nem lenne értelmesebb az ilyen dolgokat valami class-ba tenni, aminek a konstruktora foglalja le az erőforrásokat, és a destruktora felszabadítja.

Szerkesztve: 2024. 01. 26., p – 17:32

No, lelkes tákolással eljutottam odáig, hogy valgrind alá lehet vetni Linuxon, hát valami van, az biztos. Eleve arról kellene valami mondás, hogy a hívó saját maga zárja-e le a megnyitott input-fájlt. A példákban (itt és itt) nincs ilyen, de az untar.h-ban sem.

==13954==
==13954== HEAP SUMMARY:
==13954==     in use at exit: 706 bytes in 26 blocks
==13954==   total heap usage: 74 allocs, 48 frees, 83,815 bytes allocated
==13954==
==13954== LEAK SUMMARY:
==13954==    definitely lost: 312 bytes in 13 blocks
==13954==    indirectly lost: 394 bytes in 13 blocks
==13954==      possibly lost: 0 bytes in 0 blocks
==13954==    still reachable: 0 bytes in 0 blocks
==13954==         suppressed: 0 bytes in 0 blocks
==13954== Rerun with --leak-check=full to see details of leaked memory

Tökéletes lett amit elkövettél! Most már függvényen belül is létre lehet hozni crash nélkül, RAM rendben, a fordító se ad figyelmeztetést. A sört/bort/páleszt hova küldjem? Be is használtam a projektembe, frissítés fent. Fogok csinálni egy listát a használt könyvtárakról, minden szerzőnek megköszönve, amiben a tied lesz az első helyen. Szerintem küld be az Arduinonak felülvizsgálatra, rakják be a hivatalos könyvtárak közé. Hiánycikk.

Az F() jó lenne.

Egy hiba:

	if (source!=NULL && source->isOpen()) {
		source->close();
	}

 

KÖSZÖNÖM!!!

Lezártam a fájlt, de nem változott. Kb 50db fájlt szeretnék böngészőből egyszerre feltölteni, erre ez a tar cucc tökéletes. szépen fel is tölti, de utána nem marad ramom a következő reboot/crash -ig.

Ha tényleg csak ennyi kell, miért nem írod meg magad? A tar formátuma pofonegyszerű, 512 bájtos blokkokból áll. Minden fájl elején van pontosan egy darab 512 bájtos meta-infó blokk, amit a fájl tartalma követ és ennyi.

Valamikor régen írtam ilyent, kb 5 sor, nem több. Lásd itt. Ebben egyébként cpio kezelés is van, az is hasonló bonyolultságú, 5 sor. Minek ehhez külön függvénykönyvtár, pláne Arduino-n, ahol egyébként sincs túl sok erőforrás?

Ha kitömörítést is akarsz, akkor a zlib eléggé faék, de ha még az is túl sok lenne, akkor arra rengeteg inflate alternatíva van, pl. inflate.hpp, vagy miniz, vagy tinf,... stb. Nekem sikerült kemény 80 SLoC-ból megoldani (bár ez egy speciális eset, nem gzip fejlécű). Jut eszembe, az stb_image.h-ban is van egy mini zlib inflate, ami önmagában is használható és roppant erőforráskímélő implementáció.

De ha nem kell a tömörítés se, csak a tar formátumra van szükséged, akkor az tényleg nem több 5 sornál C/C++-ban.