Pregunta

Estoy escribiendo chat de sockets multiproceso en C ++ Builder 2009.
Está casi completo de acuerdo con lo que necesito hacer, pero tengo un pequeño problema. Necesito pasar el puntero TMemo * a la función CreateThread WinAPI que lo convierte en vacío *.

Lo intenté de esta manera:

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

y luego, en la función NetThread,

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

pero no funcionó :(

La pregunta es ¿cómo puedo realmente bajarlo correctamente para poder usar mi Componente Memo en este nuevo hilo?

¿Fue útil?

Solución

Llamada:

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

Lo que está sucediendo aquí es que cualquier puntero que pase como tercer parámetro se convertirá automáticamente en un puntero vacío (o en WinTerms LPVOID). Está bien, no lo cambia, solo pierde la información de tipo ya que el sistema no sabe nada sobre su objeto.

El nuevo punto de inicio de subproceso:

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

Una vez que se llama a su método de inicio de hilo. Simplemente convierta el puntero vacío al tipo correcto y debería poder comenzar a usarlo nuevamente.

Solo para aclarar otros conceptos erróneos.

Un MANGO es un puntero .
Y podría haberlo pasado como parámetro a NetThread ().

Un MANGO es un puntero a puntero bajo control del sistema que apunta al objeto que está utilizando. Entonces, ¿por qué la doble indirección. Permite que el sistema mueva el objeto (y actualice su puntero) sin encontrar a todos los propietarios del objeto. Todos los propietarios tienen identificadores que apuntan al puntero que se acaba de actualizar.

Es un concepto informático antiguo que se utiliza con poca frecuencia en las computadoras modernas debido a la capacidad del sistema operativo / hardware para intercambiar la memoria principal en el almacenamiento secundario. pero para ciertos recursos siguen siendo útiles. Hoy en día, cuando se requieren manijas, están ocultas dentro de los objetos lejos del usuario.

Otros consejos

Por favor, comprenda que un MANGO no es un puntero, sino un concepto de la API Win32. Entonces, la primera línea convierte el LPVOID en HANDLE; esto es correcto, ya que el parámetro de la rutina de subprocesos realmente se proporciona como un identificador (xxx). Sin embargo, continúa convirtiendo el MANGO en un objeto MyMemo; esto trata los bits en el identificador como si formaran una dirección, que no son.

La segunda línea realiza exactamente la misma conversión: trata un controlador como si fuera un puntero directamente.

Me pregunto por qué no estás pasando MemoChat al hilo:

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

Esto es más para tratar de aclarar el aspecto del identificador frente al puntero, porque no creo que Martin lo tenga exactamente correcto.

Un '' puntero a un puntero '' de hecho, se llama HANDLE, y es un enfoque CS común para permitir que el sistema operativo mueva físicamente los bloques de memoria asignados al montón sin el conocimiento explícito de una capa de aplicación, que siempre accede a ellos a través de controladores. Classic 68K Mac OS funciona de esta manera. Los sistemas operativos que funcionan de esta manera generalmente permiten que el código de usuario asigne memoria a través de identificadores, así como directamente fuera del montón. Este enfoque se utiliza en máquinas que no tienen hardware de administración de memoria adecuado.

Sin embargo, hay otros usos de la palabra HANDLE que toman prestada parte de la abstracción del uso anterior, pero con diferentes implementaciones. Los punteros opacos (punteros a estructuras de datos de las cuales el usuario no tiene conocimiento - lenguaje PIMPL) también se denominan comúnmente MANIJAS.

Además, el término MANGO puede usarse simplemente para denotar una "referencia". a un objeto, tal vez un índice en una matriz. Unix File Handles (= descriptores de archivo) son un buen ejemplo de esto. stdin = 0, stdout = 1, ...

Entonces, ¿cuáles de los anteriores son MANEJOS API de Windows? He visto informes contradictorios. Este documento dice:

  

Los identificadores en Win32 son números utilizados para   Identificar recursos o ventanas. Ellos   no son punteros o punteros a   punteros Piense en ellos como números de identificación.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top