2015-12-23 5 views
2

Problème: La méthode ITypeLib::GetLibAttr() alloue une nouvelle structure TLIBATTR, ce qui m'oblige à appeler le ITypeLib::ReleaseTLibAttr()? Cela rend le code trop verbeux à mon goût, et il a le potentiel de fuites de mémoire si négligé.ITypeLib: GetLibAttr et ReleaseTLibAttr

Si je cache le résultat, appelez ReleaseTLibAttr(), y a-t-il des effets secondaires ou des pièges potentiels lors de l'utilisation de la valeur mise en cache?


Le struct TLIBATTR est juste un ensemble de valeurs simples:

typedef struct tagTLIBATTR 
{ 
    GUID guid; 
    LCID lcid; 
    SYSKIND syskind; 
    WORD wMajorVerNum; 
    WORD wMinorVerNum; 
    WORD wLibFlags; 
} TLIBATTR; 

Il n'y a pas de membres qui sont eux-mêmes affectés dynamiquement. Peut-être que cela est sujet à changement?


j'ai écrit une méthode simple d'aide pour éviter la nécessité d'appeler ReleaseTLibAttr().

HRESULT MyGetLibAttr(ITypeLib* pTypeLib, TLIBATTR *pTLibAttr) 
{ 
    TLIBATTR *pTLibAttrTemp; 
    HRESULT hr = pTypeLib->GetLibAttr(&pTLibAttrTemp); 
    if (SUCCEEDED(hr)) 
    { 
     memcpy(pTLibAttr, pTLibAttrTemp, sizeof(TLIBATTR)); 
     pTypeLib->ReleaseTLibAttr(pTLibAttrTemp); 
    } 
    return hr; 
} 

void main() 
{ 
    ITypeLib *pTypeLib; 
    HRESULT hr = LoadTypeLibEx(... , &pTypeLib); 
    if (SUCCEEDED(hr)) 
    { 
     TLIBATTR libAttr; 
     hr = MyGetLibAttr(pTypeLib, &libAttr); 
     if (SUCCEEDED(hr)) 
     { 
      // Now we have a TLIBATTR object that we don't have to free. 
     } 
     pTypeLib->Release(); 
    } 
} 

Sur une échelle de 1 à 10, comment est la preuve future MyGetLibAttr() (erreur de manipulation de côté)? Y a-t-il des effets secondaires à l'utilisation du résultat mis en cache?

Je me rends compte qu'il ya un petit succès de performance (l'appel supplémentaire à memcpy()), mais la plus grande préoccupation pour nous est la maintenance de code et les fuites de mémoire.

Répondre

4

La méthode d'interface a été conçue de cette manière en 1996 car elle ne voulait pas perdre l'opportunité d'ajouter des membres à la structure. Cela ne s'est pas produit, TLIBATTR est stable depuis 19 ans. Et ne changera plus jamais, Microsoft s'est éloigné du format .tlb et utilise maintenant le format .winmd.

Si vous vous sentez mieux, le .NET Framework also copies the structure.

1

Il n'y a rien de mal avec votre code.
Vous pouvez vérifier le code source de GetLibAttr à https://github.com/alexhenrie/wine/blob/master/dlls/oleaut32/typelib.c - ITypeLib2_fnGetLibAttr.
Étant donné que vous avez chargé TypeLib, guid, lcid, syskind, wMajorVerNum, wMinorVerNum, wLibFlags ne peuvent pas être modifiés avant le prochain chargement du fichier TLB et uniquement si ce fichier a été modifié.

+1

Merci, c'est très utile! Juste curieux, y a-t-il une raison pour laquelle vous avez lié le repo alexhenrie/vin par opposition au repo vin/miroir? Pas un gros problème, juste curieux. En surface, celui-ci semble plus "officiel": https://github.com/wine-mirror/wine/blob/master/dlls/oleaut32/typelib.c – skataben

+0

@skataben. Oui, vous avez raison, ** lien officiel ** est plus correct. Il n'y a pas de raison particulière pour le lien alexherie ici. C'était juste un premier lien vers le projet de vin que j'ai trouvé. –