Как я могу корректно перевести указатель из void * в TMemo * в C ++ Builder2009?

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

Вопрос

Я пишу многопоточный чат с сокетами в C ++ Builder 2009.
Это почти завершено в соответствии с тем, что мне нужно сделать, но у меня есть небольшая проблема.Мне нужно передать указатель TMemo * в функцию CreateThread WinAPI, которая преобразует его в void *.

Я попробовал этот способ:

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

и затем, в функции NetThread,

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

но это не сработало:(

Вопрос в том, как я могу действительно правильно понизить его, чтобы я мог использовать свой компонент Memo в этом новом потоке?

Это было полезно?

Решение

Звонить:

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

Здесь происходит то, что любой указатель, который вы передаете в качестве третьего параметра, автоматически преобразуется в указатель void (или в WinTerms LPVOID).Это нормально, это не меняет его, это просто теряет информацию о типе, поскольку система ничего не знает о вашем объекте.

Новая начальная точка потока:

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

Как только будет вызван ваш метод запуска потока.Просто преобразуйте указатель void обратно в правильный тип, и вы сможете начать использовать его снова.

Просто чтобы прояснить другие заблуждения.

A ДЕСКРИПТОР - это указатель.
И вы могли бы передать его в качестве параметра NetThread().

ДЕСКРИПТОР - это указатель на указатель под управлением системы, который указывает на используемый вами объект.Так к чему же двойная косвенность?Это позволяет системе перемещать объект (и обновлять его указатель), не находя всех владельцев объекта.У всех владельцев есть дескрипторы, которые указывают на указатель, который был только что обновлен.

Это старомодная концепция информатики, которая нечасто используется в современных компьютерах из-за возможности операционной системы / аппаратного обеспечения заменять основную память на дополнительную.но для определенного ресурса они все еще полезны.В настоящее время, когда требуются дескрипторы, их прячут внутри объектов подальше от пользователя.

Другие советы

Пожалуйста, поймите, что HANDLE - это не указатель, а концепция Win32 API. Таким образом, первая строка приводит LPVOID к HANDLE - это правильно, поскольку параметр подпрограммы потока действительно задан как дескриптор (xxx). Однако затем он продолжает преобразовывать HANDLE в объект MyMemo; это обрабатывает биты в дескрипторе так, как если бы они формировали адрес, а это не так.

Вторая строка выполняет точно такое же преобразование - обрабатывает дескриптор, как если бы он был указателем напрямую.

Интересно, почему вы не передаете сам MemoChat в ветку?

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

Это больше, чтобы попытаться уточнить, что такое дескриптор и указатель, потому что я не думаю, что Мартин понял это правильно.

" указатель на указатель " действительно называется HANDLE и представляет собой общий подход CS, позволяющий операционной системе физически перемещать блоки памяти, выделенные в куче, без явного знания прикладного уровня, который всегда обращается к ним через дескрипторы. Классическая 68K Mac OS работает таким образом. Операционные системы, которые работают таким образом, обычно позволяют пользовательскому коду распределять память через дескрипторы, а также напрямую из кучи. Этот подход используется на компьютерах, на которых отсутствует надлежащее оборудование для управления памятью.

Однако есть и другие варианты использования слова HANDLE, которые заимствуют некоторые абстракции предыдущего использования, но с другими реализациями. Непрозрачные указатели (указатели на структуры данных, о которых пользователь ничего не знает - идиома PIMPL) также обычно называют РУЧКАМИ.

Кроме того, термин HANDLE можно использовать просто для обозначения «ссылки»; к объекту - может быть, индекс в массиве. Файловые дескрипторы Unix (= файловые дескрипторы) являются хорошим примером этого. STDIN = 0, STDOUT = 1, ...

Итак, что из перечисленного является РУЧКОЙ Windows API? Я видел противоречивые сообщения. В этом документе говорится:

  

Дескрипторы в Win32 - это числа, используемые для   определить ресурсы или окна. Oни   не указатели или указатели на   указатели. Думайте о них как о идентификационных номерах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top