Results 1 to 13 of 13

Thread: A/V na afsluiten wanneer ik DLL gebruikt heb

  1. #1
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,542

    Unhappy A/V na afsluiten wanneer ik DLL gebruikt heb

    In navolging van mijn Fiskaly avontuur loop ik tegen iets vreemds aan.

    Om, voor mij nog onbekende reden, mag ik niet zelf direct tegen de RESTful service van het bedrijf aanpraten, maar MOET ik gebruik maken van hun library (en als dat niet mogelijk is een "Service" executable).
    Het is een DLL die, volgens mij, met Visual Studio in het achterhoofd is geschreven en wellicht ligt daar het probleem.

    Ik kan de DLL ogenschijnlijk gewoon (explicit/dynamisch) gebruiken in Delphi (10.3.3).
    Wanneer ik n van de twee exports gebruik, krijg ik netjes een antwoord terug (een string in JSON-RPC 2.0 -formaat).
    Vervolgens sluit ik mijn testapplicatie af, geef de DLL weer vrij met FreeLibrary (dat gaat gewoon goed) en krijg dan een access violation in de destructor van TApplication op onderstaande regel:
    Delphi Code:
    1. // Knip uit destructor TApplication.Destroy - BEGIN
    2.     if TOSVersion.Check(5, 1) then
    3.       WTSUnRegisterSessionNotification(FHandle); // <==== AV
    4. // Knip uit destructor TApplication.Destroy - END

    Ik kan het probleem helemaal terugvoeren tot aan een schone eenvoudige test-applicatie met maar n form en dit in de implementation:
    Delphi Code:
    1. const
    2. // DLL can be found at: [url]https://developer.fiskaly.com/downloads/[/url] under "Library / Windows / 386"
    3.   DLLName = 'com.fiskaly.client-windows-386-v1.2.100.dll';
    4.  
    5. var
    6.   _DLLHandle: HMODULE = 0;
    7.  
    8. initialization
    9.   _DLLHandle := LoadLibrary(PChar(ExtractFilePath(ParamStr(0)) + DLLName));
    10. finalization
    11.   if _DLLHandle >= 32 then
    12.     FreeLibrary(_DLLHandle)
    13. end.

    Als ik FreeLibrary niet aanroep, dan doet de AV zich niet voor (maar dan geef ik de DLL handle natuurlijk ook niet vrij).
    Het "Leuke" is zelfs, dat als ik alles uitzet in de DPR, het probleem zich nog steeds voordoet:
    Delphi Code:
    1. begin
    2. //  Application.Initialize;
    3. //  Application.MainFormOnTaskbar := True;
    4. //  Application.CreateForm(TForm1, Form1);
    5. //  Application.Run;
    6. end.

    Kijk ik ergens overheen? Is Delphi gewoon niet compatible met deze DLL? Moet ik LoadLibraryEx (oid) gebruiken?

    Mocht je het uit willen proberen: de test applicatie staat hieronder en de DLL moet je zelf even downloaden (is te groot voor het forum)

    Alvast bedankt voor jullie expertise.
    Attached Files Attached Files
    TMemoryLeak.Create(Nil);

  2. #2
    Zou dat ding op een of andere manier een achtergrondproces starten bij het laden, wat eerst beeinidigd moet worden voor je de library kunt vrijgeven?

  3. #3
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,542
    Wat exact de reden is weet ik niet, maar ik heb zojuist een FoxPro collega gesproken die met hetzelfde probleem zit en het blijkt te liggen aan de DLL waar Delphi (en FoxPro) van over hun nek gaan.
    Mijn collega heeft een wrapper geschreven om deze DLL heen en daar zou ik wel tegenaan moeten kunnen praten (als COM-object, zucht...).

    Daar we niet veel tijd meer hebben (zo'n twee-en-een-halve week) en we dat toch al niet gaan redden laat ik dit voor wat het is en moet ik maar tegen de DLL van mijn collega aan gaan praten.
    Overigens kreeg ik ook antwoord op de vraag waarom ik niet direct tegen de API mag praten: dit schijnt een voorwaarde te zijn die de Duitse staat stelt.

    Bedankt voor het meedenken in ieder geval @Benno.
    TMemoryLeak.Create(Nil);

  4. #4
    Misschien doet hij iets mals met je application handle o.i.d., ruimt 'ie dingen op die eigenlijk door je applicatie opgeruimd moeten worden.
    Ik zou die FreeLibrary dan gewoon laten zitten.

    Uit de documentatie van FreeLibrary:
    The reference count is decremented each time the FreeLibrary or FreeLibraryAndExitThread function is called for the module. When a module's reference count reaches zero or the process terminates, the system unloads the module from the address space of the process.
    M.a.w. de ingeladen DLL wordt toch al opgeruimd bij het afsluiten.

    En ook:
    Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the library module an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process.
    Dus, bij het opruimen van de DLL wordt er een functie in aangeroepen. Wellicht doet die opruim-actie iets geks waar applicaties van over hun nek kunnen gaan.

    Kortom, ik zou die FreeLibrary lekker uitcommenten, en er een regeltje bij typen waarom dat gedaan is. Je kan uiteraard eens navragen of het een bekend probleem is, en of ze het kunnen fiksen. Maar ik zou me er verder niet al te veel zorgen over maken. Windows ruimt 'm als het goed is voor je op zodra je programma afgesloten wordt.
    Last edited by GolezTrol; 18-Mar-21 at 17:06.
    1+1=b

  5. #5
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,542
    Hmmm, ik was er altijd van uit gegaan dat je met LoadLibrary een handle aanmaakt (als in: in de address-space van Windows zelf, zoals bij openXXX en CloseHandle), die na gebruik weer vrij moet worden gegeven om niet op een gegeven moment zonder handles te zitten.

    Maar, zoals gezegd ben ik maar van het oorspronkelijke plan afgestapt (al blijf ik het niet prettig vinden om een wrapper-DLL om een andere DLL te moeten gebruiken voor iets als dit), maar gezien de tijdsdruk is het momenteel de enige snelle oplossing.
    Bedankt voor de reactie in ieder geval @GolezTrol.
    TMemoryLeak.Create(Nil);

  6. #6
    Nee hoor, het is net als met geheugen. Windows houdt bij dat het voor je proces is. Proces weg: resource weg. Het gaat er vooral om dat je, zolang je proces draait, bewust met die resources omgaat. Als je blijft claimen zonder vrij te geven kan het op een gegeven moment op zijn. Memory leaks zijn dus ook met name een issue voor langlopende processen. Je zou zelfs kunnen beargumenteren dat het beter is om niet alles vrij te geven aan het eind van je programma, want dat is alleen maar overhead, en het afsluiten duurt daardoor langer.
    1+1=b

  7. #7
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,542
    Hmmm ok, weer wat geleerd op m'n ouwe dag (ben vandaag 50 geworden).

    Bedankt voor de info, Jos.

  8. #8
    Gefeliciteerd en welkom bij de club!

  9. #9
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,542
    Quote Originally Posted by mrniceguy View Post
    welkom bij de club!
    Ach, ik kom er wel overheen.

  10. #10
    (ben vandaag 50 geworden).
    Welkom bij het genoodschap der oude lullen. Het valt mee in de praktijk hoor

  11. #11
    I7 7700K 32Gb Win10 Pro Wok's Avatar
    Join Date
    Dec 2002
    Location
    Alkmaar
    Posts
    2,016
    Ik ben het al jaren geleden worden, in de praktijk blijkt dat je min of meer zoveel bagage heb opgebouwd, dat je de "jonkies" nog menig keer van suggesties kan voorzien.
    Iets aannemen van een "oudje" gaat ze vaak te ver, maar achteraf krijg je toch vaak gelijk.
    10.3.3, Delphi2010, of Lazarus 2.0.10

  12. #12
    Member
    Join Date
    Mar 2012
    Location
    Nederland
    Posts
    60
    Beetje laat maar toch: Volgens mij wordt het afgeraden een loadlibary te doen in je initialization. Zie ook https://devblogs.microsoft.com/oldne...27-00/?p=40873. Heb je de AV ook als je in je testprogramma de loadlibrary en freelibrary verhuist naar FormCreate/Destroy?

  13. #13
    Fornicatorus Formicidae VideoRipper's Avatar
    Join Date
    Mar 2005
    Location
    Vicus Saltus Orientalem
    Posts
    5,542
    Quote Originally Posted by The_Fox View Post
    Beetje laat maar toch:
    Ach, beter laat dan nooit.

    Nee, het maakt helemaal niets uit, dat is wat ik zo frappant vind; ik had het ook oorspronkelijk gewoon in de FormCreate/FormDestroy van mijn eerste testprojectje gezet (is ook het makkelijkste, gewoon file -> new project en dan met een knop en een memo kijken of je iets kunt met de DLL).
    Ik geef de handle nu niet meer vrij (zoals hierboven al geadviseerd werd) en daar heb ik tot op heden geen last van, dus dat is wat mij betreft goed genoeg.

    Quote Originally Posted by The_Fox View Post
    Volgens mij wordt het afgeraden een loadlibary te doen in je initialization. Zie ook
    Volgens mij wordt er in die blog afgeraden om "Spannende dingen te doen" in de create code van een DLL: het is niet mijn DLL, ik wil juist de DLL van een derde gebruiken (en blijkbaar houden zij zich juist niet aan dit advies van MS)
    Last edited by VideoRipper; 12-Apr-21 at 11:25.
    TMemoryLeak.Create(Nil);

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •