0

I have a lib with some TDataModules who share a TADOConnection. I create and delete datamodules in some applications.

When I delete a datamodule, I get an EAccessViolation error. I think this is due to the fact that the datamodule wants to delete the TADOConnection, which is shared.

I tried setting the tdatamodule->tbquery->Connection property to NULL when the destructor is called, without any luck.

Why do I think the error resides in TADOConnection? Because when I build my application without a lib, I can create and delete datamodules without any problems. And when I create a lib with datamodules who have their own connection, I have no problems either.

Any help? Thanks in advance!

The error: http://oi60.tinypic.com/noyc6x.jpg

The call stack: http://oi61.tinypic.com/sgljx5.jpg

sridesmet
  • 875
  • 9
  • 19

2 Answers2

0

The TDataModule only frees what it owns. If you are sharing a single TADOConnection in multiple TDataModule instances then they cannot all own it. However, maybe you are freeing the Owner and not informing the other instances that the TADOConnection is being freed. The VCL has a mechanism for that purpose - the TComponent::FreeNotification() method. Your TDataModule objects can override the virtual Notification() method and then call FreeNotification() on the TADOConnection. That way, if the TADOConnection is ever freed, any TDataModule that is using it can act accordingly, such as setting their local pointer to NULL so they know the TADOConnection is gone.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Thank you for answering. The problem is that I don't want to delete the TADOConnection. When I delete the TDataModule, the TADOConnection should still live on, as it is used by other datamodules. Suppose I have 3 TDataModules. 1 TDataModule has an TADOConnection. The other 2 TDataModules have TQueries and TDataSources that use the TADOConnection from the first datamodule. When I delete one of the last 2 datamodules, then I get an EAccess_Violation from the first datamodule. – sridesmet Feb 03 '14 at 10:02
  • As long as the first DM is not freed then the TADOConnection will not be freed. Freeing queries does not free the Connection they are using. Your AV is related to something else. If you need to free the first DM then it cannot be set as the Owner of the TADOConnection. Have you tried debugging the AV yet? What does the debugger say? What does the call stack look like when the AV occurs? – Remy Lebeau Feb 03 '14 at 18:07
  • I've added the AV message and the call stack to the question. I do not want to free the first DM. Only the 2 other DM's, who use the first DM, need to be deleted/created on the fly. – sridesmet Feb 04 '14 at 09:21
  • That call stack is not very useful. Can you provide a [SSCCE](http://sscce.org) that causes the same error? – Remy Lebeau Feb 04 '14 at 16:37
  • Thank you for your help. The solution was adding borlndmm.dll to the project folder. – sridesmet Feb 18 '14 at 12:13
0

The solution is adding borlndmm.dll to the project folder of the application using the libraries or dll's.

From the dll/lib projects in Borland C++ Builder:

//---------------------------------------------------------------------------
//   Important note about DLL memory management when your DLL uses the
//   static version of the RunTime Library:
//
//   If your DLL exports any functions that pass String objects (or structs/
//   classes containing nested Strings) as parameter or function results,
//   you will need to add the library MEMMGR.LIB to both the DLL project and
//   any other projects that use the DLL.  You will also need to use MEMMGR.LIB
//   if any other projects which use the DLL will be performing new or delete
//   operations on any non-TObject-derived classes which are exported from the
//   DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
//   EXE's to use the BORLNDMM.DLL as their memory manager.  In these cases,
//   the file BORLNDMM.DLL should be deployed along with your DLL.
//
//   To avoid using BORLNDMM.DLL, pass string information using "char *" or
//   ShortString parameters.
//
//   If your DLL uses the dynamic version of the RTL, you do not need to
//   explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
sridesmet
  • 875
  • 9
  • 19