Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Test ride con Gowow Ori: elettrico e off-road vanno incredibilmente d'accordo
Test ride con Gowow Ori: elettrico e off-road vanno incredibilmente d'accordo
Abbiamo provato per diversi giorni una new entry del mercato italiano, la Gowow Ori, una moto elettrica da off-road, omologata anche per la strada, che sfrutta una pendrive USB per cambiare radicalmente le sue prestazioni
Recensione OnePlus 15: potenza da vendere e batteria enorme dentro un nuovo design
Recensione OnePlus 15: potenza da vendere e batteria enorme dentro un nuovo design
OnePlus 15 nasce per alzare l'asticella delle prestazioni e del gaming mobile. Ma non solo, visto che integra un display LTPO 1,5K a 165 Hz, OxygenOS 16 con funzioni AI integrate e un comparto foto con tre moduli da 50 MP al posteriore. La batteria da 7.300 mAh con SUPERVOOC 120 W e AIRVOOC 50 W è la ciliegina sulla torta per uno smartphone che promette di offrire un'esperienza d'uso senza alcun compromesso
AMD Ryzen 5 7500X3D: la nuova CPU da gaming con 3D V-Cache per la fascia media
AMD Ryzen 5 7500X3D: la nuova CPU da gaming con 3D V-Cache per la fascia media
Vediamo come si comporta il Ryzen 5 7500X3D, nuovo processore di casa AMD che fonde 6 core Zen 4 con la tecnologia 3D V-Cache, particolarmente utile in scenari come il gaming. Annunciato a un prezzo di listino di 279€, il nuovo arrivato sarà in grado di diventare un riferimento per i sistemi budget? Ecco cosa ne pensiamo.
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 30-07-2005, 12:50   #21
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
Quote:
Originariamente inviato da The3DProgrammer
Qui credo nn ci sia problema: I mutex servono a tutte le classi derivate da CResource, x cui basta dichiararli (mutex e funzione) nella classe astratta e definire il metodo CreateMutexes(...) come metodo concreto public, accessibile anke quindi da tutte le classi derivate. Più che altro nn so se si può creare qualke casino con gli HANDLE dei mutex tra DLL/eseguibile, ma nn credo cmq...
ma scusa, il metodo concreto CreateMutexes dove lo implemento?
è possibile implementare parte dei metodi nell'exe e usarli nella DLL??
e allora ho risolto...

cmq no, gli handle scambiati tra DLL ed exe non fanno casino: sono validi in tutto il processo.
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 13:01   #22
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
Quote:
Originariamente inviato da fek
CLock e' un'interfaccia (ma non usare le C, dai ), che a quanto ho capito vuoi implementare nell'exe, mentre CResource e' da implementare nella DLL, ho capito bene?
precisamente.

Quote:
Non puoi derivare l'una dall'altra, devi ragionare in termini di interfacce e composizione qui. Mi sembra che la Composizione si adatti meglio all'Ereditarieta' nel tuo problema.
ehm... ok, mi devi aiutare tu
scherzi a parte, ti ringrazio vivamente per la tua disponibilità!

Quote:
Ho bisogno di sapere:
- Chi crea gli oggetti CLock e CResource
CLock non lo so, ma CResource è creata sicuramente dalla DLL; inoltre tieni presente che la DLL non istanzia solo classi sue interne derivate da CResource, ma anche classi sue interne derivate da ulteriori interfacce astratte derivate a loro volta da CResource; cioè ad esempio:

class CResource ...
class CAccount : public CResource ...
class CAccountImpl : public CAccount ...

dove CAccountImpl è l'implementazione della DLL di CAccount; CAccountImpl è quella che di fatto viene istanziata, anche se è sconosciuta all'exe.

Quote:
- Chi implementa le interfacce
CLock in tutto il discorso è l'unica che dovrebbe essere implementata dall'exe; in teoria potrebbe anche essere implementata da ogni singola DLL che carico nel processo, ma preferisco che l'implementazione della mutua esclusione sia una sola e che stia nell'exe.

Quote:
- Il ciclo di vita dei due oggetti
dunque, per quanto riguarda il ciclo di vita le cose stanno così: non ho utilizzato un sistema di reference counting tipo quello di COM: semplicemente le DLL esportano alcune funzioni che istanziano ste classi, e poi sta all'exe la responsabilità di distruggerle quando vuole.

Quote:
E poi risolviamo il problema di assegnare un CLock ad un CResource e chi deve farlo. Male che vada puoi avere un factory method di CResource che assegna sempre il CLock e non puoi dimenticarlo; io di solito risolvo questo tipo di problemi cosi'.
capisco; quindi anche se il design ha questo difetto diciamo al limite chissene... ok, se proprio non si può risolvere altrimenti...
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 13:08   #23
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
Quote:
Originariamente inviato da cionci
Chiaro, ma dipende da quello che deve fare...
The3DProgrammer ha capito bene, se ho ben capito quello che ha capito
ciascun oggetto (non pensiamo ora alle classi, pensiamo agli oggetti già istanziati) deve avere due mutex e un paio di altri campi per gestire l'esclusione; tutti i thread hanno lo stesso puntatore di un determinato oggetto, e vedono gli stessi suoi campi; a seconda che chiamino LockRead, LockWrite, ecc., bloccano e sbloccano il mutex 1 o il 2 o entrambi, ma comunque per ogni oggetto i due mutex su cui lavorano sono gli stessi.
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 13:19   #24
The3DProgrammer
Senior Member
 
Iscritto dal: May 2000
Messaggi: 1459
class CResource {

public:

void CreateMutexes();

... //i tuoi metodi astratti


private:
HANDLE m_hMutex1,m_hMutex2;
};


ora:

siccome sarà l'eseguibile a dover lanciare createMutexes(), ti fai un bel resource.cpp in cui implementi CreateMutexes() nel progetto dell'eseguibile. Siccome mi pare di aver capito ke la DLL dovrà solo istanziare oggetti di classi derivate da CResource, nn hai bisogno di includere il .cpp dove definisci CreateMutexes() nella DLL, in quanto il codice nn è necessario (la funzione nn verrà mai eseguita, quindi dovrebbe linkare la DLL tranquillamente, al limite includi pure resource.cpp nella DLL). Così dovrebbe funzionare

ciauz
The3DProgrammer è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 13:27   #25
fek
Senior Member
 
L'Avatar di fek
 
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
Quote:
Originariamente inviato da 71104
CLock in tutto il discorso è l'unica che dovrebbe essere implementata dall'exe; in teoria potrebbe anche essere implementata da ogni singola DLL che carico nel processo, ma preferisco che l'implementazione della mutua esclusione sia una sola e che stia nell'exe.
Ok, prova a separare la classe in due allora.
E guarda i seguenti due design pattern se ti possono aiutare:

- Factory Method
- Builder

Vedi se questa idea ha senso, lato client:

Codice:
// anche qui magari ti puo' servire un factory in futuro, per ora non mi sembra

CLock* aLock = new CLockImpl();     

// qui il factory method serve
// uso una stringa, ma ovviamente puoi usare quello che ti pare per richiedere
// la creazione di un qualche tipo di risorsa in particolare

CResouce* aResource = CResource::Create("MyResourceType", aLock);

...

CResource::Destroy(aResource);
Io eviterei il reference counting come la peste, ho sempre avuto piu' problemi di quanti ne ho risolti.
Una possibilita' e' di avere un metodo statico di distruzione, invece di chiamare direttamente il distruttore, perche' e' buona norma creare/distruggere la memoria nello stesso modulo. Immagina che succede se la DLL usa un heap differente, tu pensi che la delete distrugga l'oggetto invece va a sovrascrivere memoria a caso (e mi e' successo).
Dichiare esplicitamente un distruttore privato nell'interfaccia e non implementarlo, cosi' costringi il cliente ad usare solo il tuo metodo Destroy. Se pensi che tanto nessuno sara' cosi' fesso da usare l'operatore delete quando c'e' un metodo Destroy, sappi che lo fanno (e mi e' successo pure questo). Se sei il solo a programmare, ti dimenticherai un giorno che esiste il metodo Destroy e userai la delete

In C# e Java tutti questi problemi non esistono

Ultima modifica di fek : 30-07-2005 alle 13:33.
fek è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 13:32   #26
fek
Senior Member
 
L'Avatar di fek
 
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
Quote:
Originariamente inviato da The3DProgrammer
siccome sarà l'eseguibile a dover lanciare createMutexes(), ti fai un bel resource.cpp in cui implementi CreateMutexes() nel progetto dell'eseguibile. Siccome mi pare di aver capito ke la DLL dovrà solo istanziare oggetti di classi derivate da CResource, nn hai bisogno di includere il .cpp dove definisci CreateMutexes() nella DLL, in quanto il codice nn è necessario (la funzione nn verrà mai eseguita, quindi dovrebbe linkare la DLL tranquillamente, al limite includi pure resource.cpp nella DLL). Così dovrebbe funzionare

ciauz
Cosi' rompe la convenzione che CResource e' un'interfaccia pura (con tutti i problemi che derivano da questa rottura).

L'interfaccia fra una DLL e il resto del mondo dovrebbe sempre essere esposta via interfacce pure. COM e' nato proprio con lo scopo di formalizzare questa convenzione.
fek è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 13:36   #27
fek
Senior Member
 
L'Avatar di fek
 
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
Quote:
Originariamente inviato da 71104
The3DProgrammer ha capito bene, se ho ben capito quello che ha capito
ciascun oggetto (non pensiamo ora alle classi, pensiamo agli oggetti già istanziati) deve avere due mutex e un paio di altri campi per gestire l'esclusione; tutti i thread hanno lo stesso puntatore di un determinato oggetto, e vedono gli stessi suoi campi; a seconda che chiamino LockRead, LockWrite, ecc., bloccano e sbloccano il mutex 1 o il 2 o entrambi, ma comunque per ogni oggetto i due mutex su cui lavorano sono gli stessi.
Allora metti i due mutex nell'oggetto CLock.

Puoi sempre mantenere l'interfaccia di CLock anche in CResource ed implementare un CResourceBase che contiene un'istanza di CLock passata dall'esterno e implementa l'interfaccia CResource limitandosi a delegare i Lock/Release all'oggetto CLock, per semplificare l'uso da parte del cliente.

Alla fine hai due classi ognuna con una sola responsabilita:

- CLock: si occupa della sincronizzazione
- CResource: gestisce la risorsa e delega i compiti di sincronizzazione
fek è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 13:59   #28
The3DProgrammer
Senior Member
 
Iscritto dal: May 2000
Messaggi: 1459
Quote:
Originariamente inviato da fek
Cosi' rompe la convenzione che CResource e' un'interfaccia pura (con tutti i problemi che derivano da questa rottura).

L'interfaccia fra una DLL e il resto del mondo dovrebbe sempre essere esposta via interfacce pure. COM e' nato proprio con lo scopo di formalizzare questa convenzione.
ah

nn era specificato dovesse essere un'interfaccia pura

Per curiosità, quali problemi possono scaturire? In genere, è una tecnica che funziona abbastanza bene (l'ho usata spesso)

ciauz
The3DProgrammer è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 14:13   #29
cionci
Senior Member
 
L'Avatar di cionci
 
Iscritto dal: Apr 2000
Città: Vicino a Montecatini(Pistoia) Moto:Kawasaki Ninja ZX-9R Scudetti: 29
Messaggi: 53971
Perchè non ti fai un oggetto (anzi due mi sembra di capire) un CMutex (attento che in MFC esiste già) ?
Lo metti come membro della CResource e lo inzializzi nel costruttore della CResource... Le classi derivate avranno già tali membri inizializzati...
cionci è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 15:21   #30
fek
Senior Member
 
L'Avatar di fek
 
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
Quote:
Originariamente inviato da The3DProgrammer
ah

nn era specificato dovesse essere un'interfaccia pura

Per curiosità, quali problemi possono scaturire? In genere, è una tecnica che funziona abbastanza bene (l'ho usata spesso)

ciauz
Immagina di avere campi in una classe che diachiari in un header file che condividi fra DLL e EXE e immagina di compilare DLL e EXE con due diversi valori di allineamento dei campi delle strutture. DLL e EXE pensano di lavorare sullo stesso oggetto che ha due rappresentazioni diverse in memoria e *puff* scompaiono due giorni di debugging (mi e' successo pure questo)

Oppure una qualunque variazione sul tema.

Una volta che ci si abitua a lavorare per interfacce e' tutto molto piu' semplice. Io uso quasi sempre interfacce pure come confine fra "aree" diverse anche nello stesso modulo per mantenere le interfacce stesse pulite.
fek è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 16:01   #31
The3DProgrammer
Senior Member
 
Iscritto dal: May 2000
Messaggi: 1459
interessante, nn ci avevo mai pensato

[OT]
e nelle situazioni in cui verrebbe naturale spostare funzionalità comuni nella classe base astratta, come ti comporti? Composition? Ad esempio, una classe con un template method in questo modo nn sarebbe utilizzabile...o c'è qualke trukketto?
[/OT]

ciauz
The3DProgrammer è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 16:10   #32
fek
Senior Member
 
L'Avatar di fek
 
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
Quote:
Originariamente inviato da The3DProgrammer
interessante, nn ci avevo mai pensato

[OT]
e nelle situazioni in cui verrebbe naturale spostare funzionalità comuni nella classe base astratta, come ti comporti? Composition? Ad esempio, una classe con un template method in questo modo nn sarebbe utilizzabile...o c'è qualke trukketto?
[/OT]

ciauz
Composition sempre e comunque quando sia possibile. Tendo ad ereditare molto poco e solo quando strettamente necessario (ad esempio implementazioni di interfacce).

Altrimenti faccio cose cosi':

Codice:
Animation   <- AnimationBase <- AnimationProxy (AnimationImpl)
                                   <- AnimationImpl
<- eredita
() compisizione

Chi riconosce il design pattern? (facile facile)
fek è offline   Rispondi citando il messaggio o parte di esso
Old 30-07-2005, 16:57   #33
The3DProgrammer
Senior Member
 
Iscritto dal: May 2000
Messaggi: 1459
è (dovrebbe essere ) un proxy

ciauz
The3DProgrammer è offline   Rispondi citando il messaggio o parte di esso
Old 31-07-2005, 18:39   #34
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
dunque dunque: grazie ai vostri spunti il design per il quale ho optato è il seguente: la thread-safety (i due mutex, l'intero e il flag) è gestita a parte in CLockImpl, la cui interfaccia astratta è CLock e sta nell'header condiviso. (btw: non uso MFC perché il sorgente deve essere il più possibile portabile; per ora c'è solo un file che deve essere rifatto per Linux, mettendoci anche CLockImpl saranno due).
CResource non deriva da CLock, ma tutte le classi interne della DLL derivate da CResource o da interfacce derivate da CResource (come CAccount) vengono istanziate dalla DLL sotto richiesta dell'eseguibile tramite opportuni metodi esportati dalla DLL stessa; tutti questi metodi tra i parametri vogliono anche un puntatore a un'istanza di CLock creata dall'exe.
per costringere la DLL ad implementare CResource utilizzando un'istanza di CLock, metterò in CResource un costruttore puro virtuale (si può fare, vero? ) con un parametro CLock*.
ora però vengono i problemoni: la distruzione di tutto sto macello!
come consiglia giustamente fek, conviene sempre deallocare memoria nello stesso modulo in cui la si alloca (altrimenti se i moduli usano heap differenti possiamo allegramente assistere a curiosi fenomeni cosmici); bene: qui è praticamente il contrario... le cose allocate da uno vengono deallocate dall'altro...
allora, le implementazioni di CResource o delle interfacce derivate vengono allocate dalla DLL e vengono distrutte dall'exe; inoltre ciascuna di esse contiene un'istanza di CLock creata dall'exe e deallocata dalla DLL...
per distruggere CResource posso (come suggerisce fek) metterci un metodo astratto Destroy implementato dalla DLL che deve chiama il distruttore (che metterò come membro privato per evitare che un giorno io mi dimetichi dell'esistenza di Destroy); in tal modo a distruggere le istanze di CResource è la DLL (non più l'exe), la quale quindi deve anche occuparsi di distruggere il CLock, e questo non va bene perché sennò assistiamo ai fenomeni cosmici; e io come faccio? semplice!! uso la tecnica del Destroy anche in CLock!!!
risolto! (ho capito la soluzione mentre scrivevo )
grazie a tutti, specie fek

EDIT: vorrei un ultimo vostro parere: ma è proprio necessario un design così complesso? non si può proprio fare qualcosa di più semplice?

Ultima modifica di 71104 : 31-07-2005 alle 18:41.
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 31-07-2005, 18:52   #35
fek
Senior Member
 
L'Avatar di fek
 
Iscritto dal: Oct 2002
Città: San Jose, California
Messaggi: 11794
Quote:
Originariamente inviato da 71104
EDIT: vorrei un ultimo vostro parere: ma è proprio necessario un design così complesso? non si può proprio fare qualcosa di più semplice?
Dipende da quello che stai cercando di fare.
Secondo me e' troppo complesso, sono certo che puoi migliorare le specifiche e semplificare il design.

E non usare quelle C di fronte al nome della classe!
fek è offline   Rispondi citando il messaggio o parte di esso
Old 31-07-2005, 21:08   #36
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
Quote:
Originariamente inviato da fek
Dipende da quello che stai cercando di fare.
Secondo me e' troppo complesso, sono certo che puoi migliorare le specifiche e semplificare il design.
ad ogni modo mi sono accorto che quel design non si può applicare perché non è possibile creare costruttori astratti... cosa giustissima, se pensi che un costruttore è come un metodo statico (anche se in realtà agisce su this).

e a questo punto inizio ad essere seriamente in difficoltà: non riesco a creare un oggetto implementato parzialmente da un modulo e parzialmente da un altro...
eppure imho questo è quello che va fatto: il concetto di "risorsa" nel mio progetto deve essere implementato completamente dalle varie DLL, tranne l'esclusione che preferisco implementare nell'exe (in maniera tale da avere un'implementazione unica).
certo, implementando l'esclusione in ciascuna delle DLL si risolve tutto quanto, ma è "brutto" da fare, sei d'accordo anche tu?

Quote:
E non usare quelle C di fronte al nome della classe!
uffaaaa!! ormai mi sono aibutato così!! le usa anche MFC!! (rima! )
e poi le ho usate dappertutto ormai
il massimo che posso concederti è di usare le "I" al posto nelle "C" nelle classi astratte...
71104 è offline   Rispondi citando il messaggio o parte di esso
Old 01-08-2005, 13:31   #37
71104
Bannato
 
L'Avatar di 71104
 
Iscritto dal: Feb 2005
Città: Roma
Messaggi: 7029
alla fine ho risolto così (stavolta penso proprio che sia la soluzione definitiva):
Codice:
class CLock {
public:
	virtual void LockRead() = 0;
	virtual void UnlockRead() = 0;
	virtual void LockWrite() = 0;
	virtual void UnlockWrite() = 0;

	virtual void Destroy() = 0;

};

class CResource : public CLock {
public:
	virtual CLock *GetLock() = 0;
	virtual unsigned int GetID() = 0;

	virtual COUNTER GetCounter(unsigned int uCode) = 0;
	virtual void SetCounter(unsigned int uCode, COUNTER value) = 0;

	virtual void Destroy() = 0;

};
in più ogni funzione della DLL che crea un oggetto CResource riceve in ingresso un puntatore a un oggetto CLock (che sarebbe in realtà CLockImpl).
il design una debolezza ce l'ha, ma alla fine ho detto kissene
la debolezza sarebbe che la DLL è costretta ad assegnare l'oggetto CLock che le viene passato alla risorsa che deve creare; alla fine non è neanche tanto una debolezza dal momento che quando l'exe chiama GetLock la DLL dovrà pur restituire qualcosa
se restituisce NULL sono costretto a scaricare la DLL e mostrare sulla console un messaggio di errore che dice in poche parole che quella DLL non funziona.

ultima cosa: qualcuno mi dice se la mia versione dell'esclusione va bene?
Codice:
CLockImpl::CLockImpl() {
	VERIFY(hMutex1 = CreateMutex(NULL, FALSE, NULL));
	VERIFY(hMutex2 = CreateMutex(NULL, FALSE, NULL));
	uReaders = 0;
	fWriting = 0;
}

CLockImpl::~CLockImpl() {
	VERIFY(CloseHandle(hMutex1));
	VERIFY(CloseHandle(hMutex2));
}

void CLockImpl::LockRead() {
	VERIFY(WAIT_OBJECT_0 == WaitForSingleObject(hMutex1, INFINITE));
	VERIFY(WAIT_OBJECT_0 == WaitForSingleObject(hMutex2, INFINITE));
	uReaders++;
	while (fWriting);
	VERIFY(ReleaseMutex(hMutex2));
	VERIFY(ReleaseMutex(hMutex1));
}

void CLockImpl::UnlockRead() {
	VERIFY(WAIT_OBJECT_0 == WaitForSingleObject(hMutex1, INFINITE));
	ASSERT(uReaders);
	uReaders--;
	VERIFY(ReleaseMutex(hMutex1));
}

void CLockImpl::LockWrite() {
	VERIFY(WAIT_OBJECT_0 == WaitForSingleObject(hMutex2, INFINITE));
	while (fWriting);
	fWriting = 1;
	while (uReaders);
	VERIFY(ReleaseMutex(hMutex2));
}

void CLockImpl::UnlockWrite() {
	fWriting = 0;
}

void CLockImpl::Destroy() {
	delete this;
}

Ultima modifica di 71104 : 01-08-2005 alle 13:37.
71104 è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Test ride con Gowow Ori: elettrico e off-road vanno incredibilmente d'accordo Test ride con Gowow Ori: elettrico e off-road va...
Recensione OnePlus 15: potenza da vendere e batteria enorme dentro un nuovo design   Recensione OnePlus 15: potenza da vendere e batt...
AMD Ryzen 5 7500X3D: la nuova CPU da gaming con 3D V-Cache per la fascia media AMD Ryzen 5 7500X3D: la nuova CPU da gaming con ...
SONY BRAVIA 8 II e BRAVIA Theatre System 6: il cinema a casa in formato compatto SONY BRAVIA 8 II e BRAVIA Theatre System 6: il c...
KTC H27E6 a 300Hz e 1ms: come i rivali ma a metà prezzo KTC H27E6 a 300Hz e 1ms: come i rivali ma a met&...
Grazie ai dati di ESA il calcolo della t...
Rilasciati nuovi video e immagini della ...
Gli astronauti cinesi di Shenzhou-20 son...
Mai così tanti gas serra: il 2025...
Google condannata in Germania: favorito ...
Ubisoft rimanda i risultati finanziari e...
ADATA porta i primi moduli DDR5 CUDIMM 4...
Bob Iger anticipa le novità AI di...
Microsoft Teams 'spierà' i dipend...
Michael Burry chiude Scion e fa di nuovo...
Huawei prepara i nuovi Mate 80: fino a 2...
Una e-Mountain Bike di qualità ma...
Tutte le offerte Amazon Black Friday pi&...
DJI Mini 4K Fly More Combo con 3 batteri...
Crollo di prezzo sui nuovissimi iPhone A...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 03:03.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v