Come posso eseguire correttamente il downgrade del puntatore da void * a TMemo * in C ++ Builder2009?

StackOverflow https://stackoverflow.com/questions/274841

Domanda

Sto scrivendo chat socket multi-thread in C ++ Builder 2009.
È quasi completo secondo ciò che devo fare ma ho un piccolo problema. Devo passare il puntatore TMemo * nella funzione WinTAP di CreateThread che lo inoltra per annullare *.

Ho provato in questo modo:

HANDLE xxx = MemoChat->Handle;
hNetThread = CreateThread(NULL, 0, NetThread, xxx, 0, &dwNetThreadId);
//...

e quindi, nella funzione NetThread,

TMemo* MyMemo((HANDLE)lpParam);
TMemo* MyMemo((TMemo*)lpParam);

ma non ha funzionato :(

La domanda è: come posso davvero abbatterlo correttamente in modo da poter usare il mio componente Memo in questo nuovo thread?

È stato utile?

Soluzione

di chiamata:

TMemo*     MemoChat   = // You defined that somewhere I assume
HANDLE     hNetThread = CreateThread(NULL, 0, NetThread, MemoChat, 0, &dwNetThreadId);

Quello che sta succedendo qui è che qualsiasi puntatore che passi come terzo parametro viene convertito automaticamente in un puntatore vuoto (o in WinTerms LPVOID). Va bene, non lo cambia, perde solo le informazioni sul tipo in quanto il sistema non sa nulla del tuo oggetto.

Il nuovo punto iniziale della discussione:

DWORD NetThread(LPVOID lpParameter)
{
    TMemo*   MemoChat   = reinterpret_cast<TMemo*>(lpParameter);
    // Do your thread stuff here.
}

Una volta chiamato il metodo di inizio della discussione. Converti semplicemente il puntatore vuoto nel tipo corretto e dovresti essere in grado di ricominciare a usarlo.

Solo per chiarire altre idee sbagliate.

Una MANIGLIA è un puntatore .
E avresti potuto passarlo come parametro a NetThread ().

Una MANIGLIA è un puntatore a puntatore sotto controllo di sistema che punta sull'oggetto che stai usando. Quindi perché la doppia indiretta. Permette al sistema di spostare l'oggetto (e aggiornare il suo puntatore) senza trovare tutti i proprietari dell'oggetto. Tutti i proprietari hanno gli handle che puntano al puntatore che è stato appena aggiornato.

È un vecchio concetto di informatica che viene usato raramente nei computer moderni a causa della capacità del sistema operativo / hardware di scambiare la memoria principale nella memoria secondaria. ma per certe risorse sono ancora utili. Al giorno d'oggi, quando sono richieste le maniglie, sono nascoste all'interno degli oggetti lontano dall'utente.

Altri suggerimenti

Ti preghiamo di comprendere che un HANDLE non è non un puntatore, ma un concetto dell'API Win32. Quindi la prima riga lancia LPVOID su HANDLE - questo è corretto, dato che il parametro della routine del thread è dato come handle (xxx). Tuttavia, continua a convertire la MANIGLIA in un oggetto MyMemo; questo tratta i bit nell'handle come se formassero un indirizzo - cosa che non sono.

La seconda riga fa esattamente la stessa conversione: tratta un handle come se fosse direttamente un puntatore.

Mi chiedo perché non stai passando MemoChat stesso al thread:

hNetThread = CreateThread(NULL, 0, NetThread, MemoChat, 0, &dwNetThreadId);

Questo è di più per cercare di chiarire la cosa handle vs. pointer, perché non penso che Martin abbia esattamente ragione.

Un puntatore " a un puntatore " viene infatti chiamato HANDLE ed è un approccio CS comune per consentire al sistema operativo di spostare fisicamente i blocchi di memoria allocati in heap senza la conoscenza esplicita di un livello applicazione, che accede sempre ad essi tramite handle. Il classico Mac OS 68K funziona in questo modo. I sistemi operativi che funzionano in questo modo in genere consentono al codice utente di allocare memoria tramite handle e direttamente dall'heap. Questo approccio viene utilizzato su macchine che non dispongono di un adeguato hardware di gestione della memoria.

Tuttavia, ci sono altri usi della parola MANIGLIA che prendono in prestito parte dell'astrazione dell'uso precedente, ma con implementazioni diverse. I puntatori opachi (puntatori a strutture di dati di cui l'utente non ha conoscenza - linguaggio PIMPL) sono anche comunemente chiamati MANIGLIE.

Inoltre, il termine MANIGLIA può essere usato semplicemente per indicare un "riferimento". a un oggetto - forse un indice in un array. Gli handle di file Unix (= descrittori di file) ne sono un buon esempio. stdin = 0, stdout = 1, ...

Quindi, quali dei precedenti sono MANIGLIE API Windows? Ho visto rapporti contrastanti. Questo documento dice:

  

Le maniglie in Win32 sono numeri utilizzate   identificare risorse o finestre. Essi   non sono puntatori o puntatori a   puntatori. Pensali come numeri ID.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top