Dll non libérée (Attempted to read or write protected memory.)

Signaler
Messages postés
4
Date d'inscription
mardi 20 mars 2007
Statut
Membre
Dernière intervention
21 mars 2007
-
Messages postés
4
Date d'inscription
samedi 30 octobre 2004
Statut
Membre
Dernière intervention
15 juillet 2009
-
Bonjour,

J'ai une page qui utilise une classe C# implémentant une .dll écrite en C de la manière suivante :

    //Chargement de la DLL kernel 32 afin de charger la fonction loadLibrairy
    [DllImport("Kernel32.dll", EntryPoint = "LoadLibrary")]
    private static extern IntPtr LoadLibrary(
           [In] string lpFileName
           );

    //déclaration de la fonction dans la DLL pour la décompression
    [DllImport("CompressionTrame.dll", EntryPoint = "DecompressionLZW", ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
    public static extern int DecompressionLZW(ref COMPRESSION_TRAME trame);

    //déclaration de la fonction dans la DLL pour la compression
    [DllImport("CompressionTrame.dll", EntryPoint = "CompressionLZW", ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
    public static extern int CompressionLZW(ref COMPRESSION_TRAME trame);

    // #################################################
    //                      CONSTRUCTEUR
    // #################################################
    /// <summary>
    /// Le constructeur de la classe.
    /// </summary>
    /// Chemin permettant d'accéder aux .dll

    
    public compressionCriptage(String chemin)
    {
        //chargement de CompressionTrame.dll
        LoadLibrary(chemin + "\\CompressionTrame.dll");
    }

Tout fonctionne très bien sauf dans le cas où ma page est appelée plusieurs fois de suite. Dans ce cas j'ai une erreur (cf ci-dessous)

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Exception Details: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Stack Trace:
[AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.]
   compressionCriptage.CompressionLZW(COMPRESSION_TRAME& trame) +0
   compressionCriptage.Compression(String chaine) in c:\Inetpub\...\compressionCriptage.cs:125
   communication_XXX.Page_Load(Object sender, EventArgs e) in c:\Inetpub\....communication_XXX.aspx.cs:303
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +15
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +34
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +47
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1061

 
Je pense qu'il s'agit d'un problème de libération des ressources (la .dll n'est pas encore dispo quand on a re-besoin d'elle).
Le problème est que je ne sais pas comment "libérer" ma .dll

Pour info, j'ai déjà regardé un peu sur Google et aussi du côté de
- http://nico-pyright.developpez.com/tutoriel/vc2005/interop/#LpinvokeWithCSharp,
- http://morpheus.developpez.com/dlldotnet/,
- http://laurent-dardenne.developpez.com/articles/Delphi/2005/DotNet/Destructeurs-et-Finaliseurs/#L2-10-2 etc...

et les choses ne me semblent pas beaucoup plus clair (faut il une méthode close dans la .dll?, utiliser IDisposable?..)

Merci d'avance pour votre aide.

8 réponses

Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Salut, pourquoi utilises tu LoadLibrary !?
Messages postés
4
Date d'inscription
mardi 20 mars 2007
Statut
Membre
Dernière intervention
21 mars 2007

Un de mes collègues, s'était galléré dans un autre projet pour charger lui aussi des .dll codées en C.
C'est donc sur ses conseils que j'ai importé la dll de cette manière.

Pourquoi cette question, LoadLibrary pourrait être la cause de ce blocage temporaire?
Quelle autre solution serait possible?
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
L'attribut DllImport suffit, c'est inutile d'utiliser LoadLibrary en C# ou bien pour des cas très particuliers.
Messages postés
4
Date d'inscription
mardi 20 mars 2007
Statut
Membre
Dernière intervention
21 mars 2007

En gros, tu me conseille de ne par utiliser la partie que j'ai mise sous le commentaire :
//Chargement de la DLL kernel 32 afin de charger la fonction loadLibrary
et de laisser le reste du code comme il est. Je vais voir ce que ça donne.

Y-a-t'il un attribut "inverse" de DllImport qui me permettrait de libérer la .dll quand je n'en ai plus besoin (ce qui est mon principal problème, le chargement se passant bien)? De plus, la libération de la .dll est d'autant plus importante que tout ça est destiné à une appli° WEB et donc le risque que 2 clients aient besoin de la .dll presque en même temps est assez fort.

Merci
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Oui c'est FreeLibrary mais comme LoadLibrary c'est inutile pour simplement utiliser des fonctions contenues dans une DLL, le mécanisme de chargement et de déchargement de la DLL est totalement géré par l'attribut DllImport. Une librairire peut être partagée par plusieurs client sans problèmes et heureusement.

Cela dit je ne fais pas de développement Web je ne sais donc pas ce qu'implique le chargement et déchargement d'une page web au niveau de l'attribut DllImport. mais ça ne cahnge rien au niveau du code C#, inutile d'utliser LoadLibrary dans ton cas.
Messages postés
4
Date d'inscription
mardi 20 mars 2007
Statut
Membre
Dernière intervention
21 mars 2007

J'ai enlevé LoadLibrary et laissé seulement DllImport.

- Effectivement, cela fonctionne d'un point de vue test unitaire (ça m'a permis d'alléger mon code, merci).
- Malheureusement, j'arrive de nouveau, si je solicite plusieurs fois à la suite ma page, à la situation de blocage décrite dans le message d'erreur de mon premier post.
Y-aurait-il un moyen de forcer la libération de la dll pour être sûr qu'elle sera toujours disponible quand la page fera appel à elle?

- Au passage et par curiosité, tu disais qu'utiliser LoadLibrary en C# était inutile sauf dans quelques cas particuliers, aurais-tu un exemple de cas?

Merci
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
38
Essentiellement quand on a besoin d'utiliser GetProcAdress, ça peut d'ailleurs peut etre t'aider.

http://www.csharpfr.com/codes/PINVOKE-DYNAMIQUE_36080.aspx


 
Messages postés
4
Date d'inscription
samedi 30 octobre 2004
Statut
Membre
Dernière intervention
15 juillet 2009

J'ai un problème presque similaire. As-tu réussi à résoudre ton problème ?