Comment puis-je correctement décaler le pointeur de void * vers TMemo * dans C ++ Builder2009?

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

Question

J'écris dans C ++ Builder 2009.
Il est presque complet conformément à ce que je dois faire mais j'ai un petit problème. Je dois passer le pointeur TMemo * dans la fonction CreateThread WinAPI qui l’amène à vide *.

J'ai essayé de cette façon:

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

puis, dans la fonction NetThread,

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

mais cela n'a pas fonctionné: (

La question est de savoir comment je peux vraiment l'abaisser correctement pour pouvoir utiliser mon composant Mémo dans ce nouveau fil?

Était-ce utile?

La solution

Appeler:

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

Ce qui se passe ici est que tout pointeur que vous passez en tant que troisième paramètre est automatiquement converti en un pointeur vide (ou dans WinTerms LPVOID). Bien, cela ne change rien, il perd simplement les informations de type car le système ne sait rien de votre objet.

Le nouveau point de départ du thread:

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

Une fois que votre méthode de démarrage du fil est appelée. Reconvertissez simplement le pointeur vide dans le type correct et vous devriez pouvoir recommencer à l'utiliser.

Juste pour dissiper les idées fausses.

Un HANDLE est un pointeur .
Et vous auriez pu le passer comme paramètre à la NetThread ().

Un HANDLE est un pointeur sur un pointeur sous contrôle du système qui pointe sur l'objet que vous utilisez. Alors pourquoi le double indirection. Il permet au système de déplacer l'objet (et de mettre à jour son pointeur) sans rechercher tous les propriétaires de l'objet. Les propriétaires ont tous des poignées indiquant le pointeur qui vient d'être mis à jour.

Il s’agit d’un concept informatique ancien qui est rarement utilisé dans les ordinateurs modernes en raison de la capacité du système d’exploitation / du matériel informatique d’échanger la mémoire principale vers un stockage secondaire. mais pour certaines ressources, ils sont toujours utiles. De nos jours, lorsque des poignées sont requises, elles sont cachées dans des objets éloignés de l'utilisateur.

Autres conseils

S'il vous plaît, comprenez qu'un HANDLE n'est pas un pointeur, mais un concept de l'API Win32. Donc, la première ligne lance le LPVOID sur HANDLE - c'est correct, car le paramètre de la routine de thread est vraiment donné sous la forme d'un handle (xxx). Cependant, il continue ensuite à convertir le HANDLE en un objet MyMemo; cela traite les bits de la poignée comme s’ils formeraient une adresse - ce qu’ils ne sont pas.

La deuxième ligne effectue exactement la même conversion - elle traite un descripteur comme s'il s'agissait d'un pointeur direct.

Je me demande pourquoi vous ne transmettez pas MemoChat au fil:

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

C’est davantage pour essayer de clarifier le problème du contrôle par rapport au pointeur, car je ne pense pas que Martin l’ait parfaitement.

Un "pointeur sur un pointeur" s'appelle en effet HANDLE et est une approche commune de CS qui permet au système d'exploitation de déplacer physiquement des blocs de mémoire alloués au tas sans la connaissance explicite d'une couche d'application, qui y accède toujours via des handles. Classic 68K Mac OS fonctionne de cette manière. Les systèmes d'exploitation qui fonctionnent de cette manière permettent généralement au code utilisateur d'allouer de la mémoire via des poignées ainsi que directement à partir du tas. Cette approche est utilisée sur des machines ne disposant pas du matériel de gestion de la mémoire approprié.

Cependant, il existe d'autres utilisations du mot HANDLE qui empruntent une partie de l'abstraction de l'utilisation précédente, mais avec des implémentations différentes. Les pointeurs opaques (pointeurs vers des infrastructures de données dont l'utilisateur n'a aucune connaissance - idiome PIMPL) sont aussi communément appelés HANDLES.

De plus, le terme HANDLE peut être utilisé simplement pour désigner une "référence". à un objet - peut-être un index dans un tableau. Les descripteurs de fichiers Unix (= descripteurs de fichiers) en sont un bon exemple. stdin = 0, stdout = 1, ...

Alors, lesquels des API ci-dessus sont des HANDLES API? J'ai vu des rapports contradictoires. Ce document dit:

  

Les poignées dans Win32 sont des nombres utilisés pour   identifier des ressources ou des fenêtres. Ils   ne sont pas des pointeurs ou des pointeurs vers   pointeurs. Considérez-les comme des identifiants.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top