12
votes

Les classes de pointeur intelligentes à utiliser?


6 commentaires

Qu'essayez-vous de faire? Com Automation à une autre application? Hébergement d'un contrôle ActiveX? Fournir une interface COM sur votre application?


Vous voudrez peut-être inclure une discussion sur les emballages intelligents BSTR.


Quel que soit un moment, mais je me souviens d'avoir utilisé CcompTR, je suis sûr.


@Kenny, l'un des éléments ci-dessus fera le travail, ils sont identiques à environ 80%.


@Morechilli - Lorsque je choisis un wrapper, j'utiliserais probablement l'emballage BSTC équivalent.


Faites que cinq .


4 Réponses :



1
votes

J'ai utilisé les deux premiers, CCompTR et _COM_PTR_T.

On dirait que vous avez déjà lu sur la différence avec des erreurs et une manipulation des exceptions, choisissez donc celle que vous avez préférée, ou qui convient parfaitement au reste de la manipulation des erreurs de votre code.


0 commentaires

4
votes

Si vous utilisez le type de bibliothèque importation, il générera du code en fonction de _com_ptr_t et des classes de support COM associées. Allez-y et utilisez ceux-ci si vous utilisez simplement des trucs de ces bibliothèques.

Si vous écrivez un code basé sur ATL, utilisez CCompTR et les autres classes ATL.

Les choses peuvent devenir laids si vous avez besoin de mélanger et de faire correspondre les deux types, mais vous devriez probablement simplement vous mettre à l'aise avec les deux et utiliser le plus de sens pour tout ce que vous faites à l'époque.

La bonne chose est que vous ayez la source de toutes ces choses, vous n'avez donc pas à ne pas compter que sur la documentation (qui n'a pas eu beaucoup de soin car .net est apparu).


1 commentaires

Mélanger et assortir n'est pas si mal; Vous pouvez transmettre le pointeur d'interface brute d'avant en arrière. De plus, CCompTR (avec le reste de ATL) est très pratique pour le confinement ActiveX. ATL n'est pas seulement pour les serveurs COM.



2
votes

Depuis que vous demandez un style "propre et moderne" C ++, et donnez-vous un exemple à titre d'exemple, je vais lancer deux autres: std / boost :: partagé_ptr et boost: : intrusion_ptr . L'intrusion_ptr est évidemment le choix plus naturel, car les objets COM ont un mécanisme de comptage de référence intrusif. Shared_Ptr fonctionne aussi bien, il vous suffit d'utiliser un déterome personnalisé qui appelle iunknown :: version (version () et une petite fonction génératrice d'objet qui fait le iunknown :: addréf () et renvoie le pointeur intelligent.

Je vais habituellement avec le intrusion_ptr , alors je vais expliquer cela plus en détail. Tout d'abord, bien sûr, intrusion_ptr_add_ref et intrusif_ptr_release doivent être implémentés pour tous les iunknown s. Le constructeur intrusion_ptr a déjà une fonctionnalité pratique pour ignorer l'ajout d'une autre référence, car de nombreuses fonctions COM feront le addref () pour vous.

Il y a maintenant un problème avec cette approche: l'intrusion_ptr n'expose pas son pointeur nu sous-jacent comme certains des autres pointeurs COM. Il s'agit d'un problème car un moyen courant de créer des objets COM consiste à transmettre un pointeur à un pointeur à une fonction de création dans un autre objet. Puisque vous ne pouvez pas transmettre la intrusion_ptr dans ces fonctions, vous vous retrouvez avec des pointeurs nus temporaires maladlus utilisés pour initialiser la intrusion_ptr. Ce n'est pas très élégant, sans parler de l'exception (si vous en avez besoin du tout avec le code COM, ce qui ne jette naturellement pas d'exceptions. Je traduisez les erreurs COM dans les exceptions.)

Ainsi, ce que je fais ici est d'utiliser une autre fonction d'outil qui active une fonction qui prend une fonction COM et renvoie une appelable sur laquelle n'importe quel paramètre d'un pointeur à pointer-t-à-T peut être ou une référence à un intrusion_ptr. Tout le reste est comme la "fonction d'entrée". Ces fonctions font ensuite tout le convertir entre T ** et intrusion_ptr & pour moi. Par exemple, HRESULT CreateBuffer (ibuffer ** bufferout, Taille INT) devient un appelable avec la signature HRESULT CreateBuffer (Instriction_ptr & tamperout, Taille Int) . Ils sont un peu fastidieux d'écrire pour des arités "toutes", à moins que vous n'ayez un générateur de code, beaucoup de patience, ou que je présume des modèles variadiques. Mais une fois que vous les avez, cela rend en fait travailler avec com très gentil.


0 commentaires