8
votes

Allocation de mémoire et distribution de la mémoire sur les limites de la DLL

Je comprends que les allocations de mémoire fabriquées dans une DLL soit ensuite libérée dans une autre peuvent causer toutes sortes de problèmes, notamment en ce qui concerne le CRT. Ces types de problèmes sont particulièrement problématiques en matière d'exportation de conteneurs STL. Nous avons déjà connu ces types de problèmes (lors de la rédaction de plugins Adobe personnalisés liés à nos bibliothèques) et nous avons travaillé autour de ces problèmes en définissant notre propre allocator que nous utilisons dans tous nos conteneurs, par exemple: xxx

Cela a bien fonctionné lorsque vous passez des types à / à partir de notre code, mais nous avons eu un problème dans lequel nous devons maintenant appeler une fonction dans le SDK d'Adobe qui renvoie un vecteur peuplé qui provoque un crash quand il sort hors de portée.

Évidemment, c'est un problème de la mémoire étant attribué dans le SDK d'Adobe appartenant à un tas différent d'un tas différentiellement lorsque c'est enfin libre de mon code. Donc, je pense que je pouvais peut-être faire quelque chose d'intelligent comme d'une manière d'une manière ou d'une autre manière ou d'exporter l'allocator utilisé dans leur SDK afin que je puisse l'utiliser pour nettoyer les conteneurs retournés de leurs fonctions.

Je regarde aussi écrire une couche d'emballage ou une sorte de couche de pépage dans laquelle les conteneurs STL seraient fermés en toute sécurité entre mon code et le SDK ( bien que cela sonne très désordonné ).

Alternativement, je suis également en regardant en utilisant getprocessheaps pour identifier le tas utilisé à partir du SDK et essayer de se libérer de ce tas, au lieu du tas par défaut.

a des conseils sur la façon dont nous peut résoudre ce problème?


0 commentaires

3 Réponses :


0
votes

Vous pouvez essayer de chercher à voir s'il existe des règles formelles C ++ pour ce qui se passe lorsqu'une exception est lancée dans une DLL et surpris dans une autre, puis est hors de portée - il semble très similaire. Pour les exceptions, je pense Vous devez fournir un constructeur de copie avec une signature spéciale, bien que je ne sois pas sûr exactement ce que c'est.


0 commentaires

8
votes

assez ironiquement, les bibliothèques d'Adobe Source ont un Adobe :: Capture_allocator < / a> classe qui a été écrite spécifiquement avec ce type de sécurité DLL à l'esprit. La manière dont il fonctionne est de capturer le nouveau nouveau et Supprimer à ce stade, il est instancié et de les transporter à la fois pour la durée de vie de l'objet. (Voir Adobe :: new_delete_t pour plus de détails sur la façon dont il fait , surtout la mise en œuvre ici .) Les localogocations ont lieu avec le supprimer Capturé < / Code> routine, garantissant que, peu importe où vous êtes, vous supprimez avec le bon Supprimer .

Vous pouvez voir capture_allocator utilisé sur tout le version_1 Types dans les bibliothèques Source Adobe, telles que Adobe :: Any_regular_t et Adobe :: copy_write . capture_allocator doit également être compatible avec tous les types de conteneurs STL.

mise à jour: capture_allocator n'est pas conforme à la normalisation car il conserve l'état. Cela ne devrait pas être un gros obstacle à sa convivialité, mais cela signifie que son utilisation n'est pas garantie de travailler avec des conteneurs conformes standard.


1 commentaires

Il s'agit d'une technique très courante, je l'ai vue en C aussi où une bibliothèque exige que ses utilisateurs fournissent un rappel d'allocation / de désaffectation via une sorte de point de bibliothèque init ().



2
votes

Pour le moment, nous travaillons sur une DLL qui expose la fonctionnalité C ++ via une interface C (pour le souci de C # étant capable d'utiliser ladite DLL).

Par exemple: la DLL a une structure mystruct_s l'interface Expose les fonctions suivantes: p>

interface.h strong> p> xxx pré>

interface_types.h strong> p >

#include "interface_types.h"
#include "interface.h"

void main()
{
    myStuct_s * x = CreateTheStruct;
    DoSomethingToTheStruct(x);
    DestroyTheStruct(x);
}


1 commentaires

@Maciek: interface.h doit contenir des fonctions non lignes. En apportant les fonctions en ligne, ils seront compilés dans l'unité de compilation de ventilidecpplfile.cpp, qui ruine le concept.