Prof A Olowofoyeku (The African Chief) wrote:
On 12 Mar 2003 at 1:13, Frank Heckenbach wrote:
[...]
"Libraries can be built from multiple units. In this case, the library source file is frequently reduced to a uses clause, an exports clause, and the initialization code."
"You can put exports clauses in the interface or implementation section of a unit. Any library that includes such a unit in its uses clause automatically exports the routines listed the unit's exports clauses-- without the need for an exports clause of its own."
It gets even wierder ... :-(
This is because of the nature of Windows "libraries" (i.e., DLLs), which are nothing more than special executables that export routines. A "library" under unix is not an executable of any kind - as far as I am aware.
In fact, (some?) ELF shared libs are executabled which can be executed for special purposes (ldd etc.). But usually they're not executed on their own, but linked into other processes.
I don't know the technical details under Windows, but that's irrelevant. The end result is that they contain some routines etc. (which have names) and which are made available to programs that use them. The same applies to shared libs under Unix and even to static libs. The difference, whether they're copied (in the exectuables and/or in memory) or shared has no bearing on the program's behaviour (leaving aside obscure things like self-modifying code or code that relies on specific addresses of routines).
It's irrelevant because we're talking about program language syntax here, not low-level details such as how dynamic linking works. I know that many Dos/Windows compilers mix them up (also BP does), but please try to keep them apart, otherwise we'll get nowhere.
[...]
Well, it can - sort of - if you have exports clauses in the units themselves. I also came across something:
"Type Switch Syntax {$ObjExportAll On} or {$ObjExportAll Off} Default {$ObjExportAll Off} Scope Global The {$ObjExportAll On} directive exports all symbols in the unit file in which it occurs. This allows the C++ compiler to create packages containing Delphi-generated object files."
Seems also very strange. At least in BP it's quite clear that interface declarations are exported and implementation declarations are not. I don't see any reason for deviating from this. If you want to export something, just write it in the interface.
That is always the case for units. What we are talking about here is exporting routines from a unit via a "library". The problem is the fact that a "library" (i.e., DLL) needs to have an "exports" clause in order to allow the programmer to specify precisely what he wants the DLL to export. This is the standard method of doing it. The above attempts to provide ways of allowing programmers to not have that exports clause in the DLL source itself - which means they need to specify what to export somewhere else - so a DLL source can then be as simple as this;
library foo; uses bar1, bar2, bar3, bar4; begin end.
Without the above switch (or without using exports clauses) in the bar(n) units, we couldn't have the above - but we would rather need something like this;
library foo; uses bar1, bar2, bar3, bar4; exports bar01 name 'myBar1', bar02 name 'myBar2', bar03 name 'myBar3', bar04 name 'myBar4'; begin end.
Well, either I'm overlooking quite a few things, or they just like to make things unnecessarily complicated for no good reason.
I think that we've got the wires crossed somewhere ;-). What they are doing is trying to find ways round the principle that a library must have an exports clause that states what is to be exported from it. They could, of course, simply have revised that principle itself - but I am a subscriber to the view that the programmer must specify for himself (somewhere) what the library should export.
Yes, so either with explicit export statements as in the latter example, or by re-exporting everything imported via `uses' (in a library, this would seem a useful default to me -- which is why I got to libraries in this thread originally).
What seems strange is (a) that units decide on behalf of the library what to export (what if a unit authors write some export statement, thinking of a particular library, and someone else wants to use the unit in another library and not export the stuff), and (b) that via that switch, things in an implementation part can be exported.
But maybe there's another confusion going on here -- the confusionn between exporting and providing linker names ("non-static functions" in C). In GPC, implementation routines by default get no linker name, but it's possible to specify one (with `asmname', subject to the syntax changes) -- though I'm not really sure if that's a good feature ... But that doesn't mean they're exported.
Frank