Como posso corretamente downcast o ponteiro de void * para TMemo * em C ++ Builder2009?

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

Pergunta

Estou escrevendo multi-thread tomada de bate-papo no C ++ Builder 2009.
É quase completo em conformidade com o que eu preciso fazer, mas eu tenho um pequeno problema. Eu preciso passar o TMemo * ponteiro em função CreateThread WinAPI que upcasts-lo para void *.

Eu tentei desta forma:

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

e, em seguida, em função NetThread,

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

mas didn`t trabalho: (

A questão é como eu posso realmente abatido-lo corretamente para que eu possa usar meu Memo Component neste novo segmento?

Foi útil?

Solução

Chamada:

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

O que está acontecendo aqui é que qualquer ponteiro que você passa como o terceiro parâmetro é ser auto convertido em um ponteiro nulo (ou em WinTerms LPVOID). Isso é bom não mudá-lo apenas perde o tipo de informação que o sistema não sabe nada sobre o seu objeto.

O novo Tópico Ponto inicial:

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

Uma vez que seu início rosca método é chamado. Apenas converter parte de trás ponteiro void para o tipo correto e você deve ser capaz de começar a usá-lo novamente.

Apenas para esclarecer outros equívocos.

A identificador é um ponteiro .
E você poderia ter passado como o parâmetro para o NetThread ().

A alça é um ponteiro para ponteiro sob controle sistema que aponta para o objeto que você está usando. Então, por que o duplo engano. Ele permite que o sistema para mover o objeto (e atualizar seu ponteiro) sem encontrar todos os proprietários do objeto. Os proprietários têm alças que aponte para o ponteiro que acabou de ser atualizado.

É um conceito de ciência da computação à moda antiga que é utilizado com pouca frequência em computadores modernos devido à capacidade OS / Hardware para a memória principal de swap para armazenamento secundário. mas para determinado recurso que ainda são úteis. Hoje em dia, quando alças são necessários eles estão escondidos dentro de objetos longe do usuário.

Outras dicas

Por favor, entenda que um identificador é não um ponteiro, mas um conceito da API Win32. Assim, a primeira linha lança a LPVOID para lidar com - isso é correto, como o parâmetro da rotina fio realmente é dado como um manípulo (xxx). No entanto, em seguida, passa converter o identificador para um objeto MyMemo; este trata os bits no punho como se eles formariam um endereço - o que eles não são

.

A segunda linha faz exatamente a mesma conversão -. Ele trata um punho como se fosse um ponteiro diretamente

Eu me pergunto por que você não está passando MemoChat própria para o segmento:

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

Este é mais para tentar esclarecer a coisa ponteiro punho contra, porque eu não acho que Martin tem o valor correto.

A "ponteiro para um ponteiro" é realmente chamado de uma alça, e é uma abordagem comum CS para permitir que o sistema operacional para mover fisicamente blocos de memória heap-alocado ao redor sem o conhecimento explícito de uma camada de aplicação, que sempre acessa-los via alças. Clássico 68K Mac OS funciona desta forma. OS'es que o trabalho desta forma tipicamente permitem código do usuário para alocar memória através de alças, bem como diretamente fora da pilha. Esta abordagem é usada em máquinas que não possuem hardware de gerenciamento de memória adequada.

No entanto, existem outros usos da palavra PUNHO que emprestam a alguns dos a abstração do uso anterior, mas com diferentes implementações. ponteiros opacas (ponteiros para estruturas de dados dos quais o usuário não tem conhecimento - Pimpl idioma) também são comumente chamados de alças.

Além disso, o termo identificador pode ser utilizado simplesmente para denotar uma "referência" para um objeto - talvez um índice para uma matriz. Identificadores de arquivo Unix (= descritores de arquivos) são um bom exemplo disso. stdin = 0, stdout = 1, ...

Então, qual das alternativas acima são alças API do Windows? Eu vi relatos conflitantes. Este documento diz:

Handles em Win32 são números usados ??para identificar recursos ou janelas. Eles não são ponteiros ou ponteiros para ponteiros. Pense neles como números de identificação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top