Accendo / Publikované

Access Violation – Windows 2003 SP2 SOAP problém Delphi 7

 

Autor: Libor Bešenyi

Dátum: 2.6.2009

 

Môže sa Vám stať, že keď používate SOAP klienta vo Vašej aplikácii, ktorá doteraz fungovala správne, na serveri MS Windows 2003 SP2 nepôjde a RIO komponent zahlási Access Violation.

 

V prvom rade skontroluje, či máte nainštalovaný Update 1 pre Delphi 7 – ktorý rieši závažné chyby.

 

Ak máte a chyba sa stále prejavuje, je tu riešenie – premigrujte aplikáciu na Borland Delphi 2006+.

 

Ak nemôžete, je tu najhoršie riešenie. Je nutný zásah do zdrojových kódov Delphi. Situácii, ktorá nás ku tomu vedie určite existuje. Niekto môže byť v procese migrácie väčšieho projekty, ale tento bug fix treba urobiť do starej verzie. Niekto môže končiť vývoj v Delphi, ale nový produkt sa ešte nevydal. Nech je ako chce, toto je fekálne riešenie, preto zvážte, či to stojí za to.

 

Keď sa pozrieme na zdrojáky RAD 2009 (v ktorom SOAP na Win2003 chodí), tak hneď zistíme, že Delphi prerobilo prístup ku pamäti. SP2 v Win2003 upravili správu pamäti a miesto, kde si doteraz Delphi alokovalo, je už systémom zakázané. Takže poďme upravovať:

 

-         Tools / Environment Options / Library / Library path – pridajme cestu na SOAP komponenty Delphi (napr. c:\Program Files\Borland\Delphi7\Source\Soap\) – nutné, aby sme mohli šahať do zdrojákov a aby sa prebuildili komponenty.

-         Zožeňme si zdroják (napr. z RAD Studio 2009) PrivateHeap.pas a nakopírujme ho do adresára.

-         Nájdime inkriminovaný riadok s chybnou alokáciou pamäte (nový unit zaregistrujme v uses, samozrejme):

 
GetMem(IntfStubs, (Length( IntfMD.MDA) + NumEntriesInIInterface) * StubSize);

 

            Nahraďme ho týmto riadkom:

 

CodeHeap.GetMem(IntfStubs, (Length(IntfMD.MDA) + NumEntriesInIInterface) *
StubSize);

 

-         Upravme aj uvoľňovanie alokovanej pamäti v deštruktore (ináč bude kričať „Invalid Operation“ pri uvoľnení) a nahradíme IntfStubs uvoľnenie pôvodné, za toto:

 

  if Assigned(IntfStubs) then
    CodeHeap.FreeMem(IntfStubs);