0
votes

I am creating a runtime package which contains classes that my main application can use, but I'm having problems with the data access. My main app contains a TDatabase which points to a BDE alias. At runtime my package is dynamically loaded, and a method invoked in the package which creates a TQuery and opens it, populates an object with the returned data and then returns the object to the main app. The TQuery uses the TDatabase in the main app to connect to the database. All this works fine, but when I close the app I get an access violation: "Project C:...GUI.exe faulted with message 'access violation at 0x7c9102db: write of address 0x00040ffc'. Process Stopped. Use Step or Run to continue". If my method creates the TQuery but doesn't open it then this error does not occur. I have no idea why this happens! When I close th app my TQuery is closed and freed ok, my package is unloaded ok, but after the form is destroyed the error occurs. I'm using Delphi 5 BTW, I've tried to be brief so if I have missed out any helpful info let me know, any help gratefully received.

Thanks

p.s. I know that using Delphi 5 and BDE is archaic but I'm stuck with it for now!

3

3 Answers

1
votes

What if you don't free your TQuery? I mean, try not to free your TQuery object when application terminates.

0
votes

This happened with me using dbExpress, the finalization section would fire before a datamodule destructor, when application was Abort()ed and that caused a lot of head ache.

So, my guess would be that

  • BDE's connection driver (or some other resource) is finalizing before the destruction of something that uses it, therefore attempting to finalize the connection twice.

I say driver because those are usually only loaded/initialized on demand, thus it wouldn't fault if it wasn't used. So, maybe when your package is unloaded it finalizes the drivers.

Try this:

  • load your package,
  • use the TQuery contained in the package,
  • unload your package,
  • use another TQuery created in the main application,

and see if this works without raising exceptions. If it doesn't work then I guess I could be right, and we'll try to figure out how to make this work.

God bless!

0
votes

Sounds like a unit initialization/finalization order issue. Usually that is determined by the order of units in the uses lists, and what packages your package requires.

Best way to try to solve it is to debug Delphi with Delphi, or your package with a .EXE.
The last one is important, because older Delphi versions won't always find the symbols for your package if you start debugging with your EXE.

Steps

  1. Start a Delphi that does not contain your package
  2. Load your package in Delphi
  3. Set the host of your package to be Delphi
  4. Compile your package with full debug information, and enable the option 'debug DCU's'
  5. Run your package (it should now load Delphi, then your package)
  6. Terminate Delphi
  7. Watch the call stack when the AV occurrs

You might want to set breakpoints to watch your initialization/finalization order (see this post, the references and the comments for a discussion on that).

Then fiddle with your uses lists and package requirements sections.

--jeroen