Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

Code Block
TestFile                            DCL_System_IO_AsciiFile
AnotherTestFile                     DCL_System_IO_AsciiFile
! etc

Pool management

I decided to treat this as a pool management problem. I needed a list of all of the available file layouts, and a way to mark a file as in use. Then in the constructor I would check the list and initialize the class instance with an available file layout. 

...

I wish I'd made this change sooner - the refactoring wasn't all that difficult, the class is much, much easier to use, and I've added a new pool tool to the kit in the event I need similar functionality somewhere else. 

Note
titleLate breaking weirdness

After I posted this article and a shorter one titled Class exporter now a pre-build task (DCL) I decided I needed to deal with a circular reference problem in the class exporter, which now uses DCL_System_IO_AsciiFile to read its list of class headers to parse from a text file.

Originally CreateDCLExportFile made use of DevRoadmapsClarion.DLL, but because CreateDCLExportFile is now a pre-build task for the class library there's a risk that a change to the class library could cause a runtime failure which would break the class library build. With the build broken, how do I then create the EXP so the build can succeed? Big problem.

But wait, that's no problem at all. I can do the same thing with CreateDCLExportFile that I did with ClarionTest - compile in the required classes so I don't need the DLL. Brilliant!

Except when I did that, CreateDCLExportFile GPFd.

I actually resorted to the debugger to see what was the problem. And I found that in an EXE my AsciiFilePool class was not being instantiated. Why, I can't imagine.

The fix was to change AsciiFilePool to a typed class and set up a reference:

 

Code Block
AsciiFilePoolType                       class(DCL_System_Pool),type
Construct                                   procedure
										end
AsciiFilePoolInstance                   &AsciiFilePoolType

The first line of my DCL_System_IO_AsciiFile.Construct method now has this line:

Code Block
if AsciiFilePoolInstance &= null then AsciiFilePoolInstance &= new AsciiFilePoolType.

This way I'm guaranteed to have a pool instance.

I find it quite strange that a module-level instance should need to be instantiated for EXEs but not DLLs, but there it is. If anyone can shed light on this please do so.


Info
titleWeirdness mystery solved!

After further investigation I discovered the reason for the GPF. It wasn't that the pool instance wasn't created, it was that in the EXE the pool instance was created after the file class instance. That meant the file class constructor fired before it had a pool instance to work with. In the DLL however the pool instance was created first.

I'm not sure why that should be the case; perhaps in the EXE anything in declared the module is only created when the module itself comes into scope (as when the class is instantiated), while in the DLL all static declarations are automatically instantiated on DLL loading. But that's just speculation on my part.

In any case, taking control of the pool object's instantiation solves the problem.