To INC File or Not To INC File and declare externals in each APP

,
Tags: #<Tag:0x00007fc0d0706000> #<Tag:0x00007fc0d0705e98>

I have been a Clarion programmer forever; but, it seems like I have this internal struggle the past 30 years or so on whether it is a best practice to use “global” INC files in our multi-DLL applications? Or, to add ‘Insert Module’ for the external DLL’s and then prototype the needed procedures from the DLL? It seems like I remember Bob Foreman (not taking his name in vain/vein/vane [choose one]…) saying that there is less overhead with the second method; but, I may have been on crack that day.

I suspect that there is a probable middle ground, where if you are using say 75% of the DLL, you go with the INC file; but, if you are only using a handful, you prototype them. What say you?

Computers are so fast I would not worry about the impact on build time of extra unused procedures.

The INC file insures you are using the exact same Prototype in all places. One thing I know is local to each APP is the default value e.g. (LONG DateWanted=-1). If you decide to change that Default= you must fix each APP. Using an INC file saves that.

You can generate the INC for each APP with a fairly simple Template.

I use the template and produce INC files for all of the DLL’s in the application suite. Just getting ready to switch over to Clarion 11 and wondered if there is a “better” way of doing it. At least changing nothing will save me work…

BTW, I believe the contention was that if you use the INC file, that when the DLL is loaded, it loaded the entire DLL into memory. If you used the second method, it only pulled the specified procedures into memory. But as I say that, I think that would require a lot more intelligence in the Clarion runtime libraries - not sure that it is there… And, then again, maybe that was only when you were compiling with the lib method. (You’d think I’d remember stuff from a mere 25 years ago…)

IIRC in 16-bit there was some setting (maybe EXP) that reduced paging in the DLL. In 32-bit the way to reduce paging in is to set a Base Address for each DLL to be unique.

While the INC file may list everything exported the Smart Linker will only link in procedures actually called by code that actually runs, by “link in” I mean build an Import Table. You can see that in Depends.

That is inaccurate. DLL’s can’t “partially load”. There may be arguments for this when it’s in LIB mode, but only in cases where the LIB was not one of your own apps. So basically the point is moot and can be ignored.

DLLs do “partially load” into physical memory …

DLLs are “loaded” as Memory Mapped files which means the Disk file is mapped into your virtual 2GB address space. Only the pages required are actually loaded into physical memory, ideally that would mostly be header pages like the exports table. As you access procedure code those pages are loaded into physical memory, as those are not needed they are discarded.

Data pages are “Copy on Write” so if they are modified when they are no longer needed they are retained in memory. When memory runs short they may be written to the swap file.

If rebasing is required on a DLL the code pages are modified so the “Copy on Write” occurs and the code pages must be retained or written to swap.

So to optimally partially load DLLs set a unique base address in each DLL APP.

I normally add the ones I need as an external call. However, I also use the free RYB template Prototype Explorer in each application to produce a file that could be included into a DLL.

The free template can be gotten from https://github.com/RobertArtigas/RYB. Documentation (work in process) is at https://github.com/RobertArtigas/RYB/wiki.

The specific template is documented at https://github.com/RobertArtigas/RYB/wiki/Prototype-Explorer and contains a sample listing of the *.INC file output.

1 Like