Dr A A Olowofoyeku wrote:
Instead of "Foobar" for an identifier `FooBar' declared in a unit/module `Baz', we could probably use `baz.foobar' (or `baz$foobar'), all lower-case, without risking name clashes with the libc.
Since such routines should be calleable from programs with the declaration "baz.foobar", it might be that the dot notation would be preferable to the "$" notation (but of course, it might not make any difference to the compiler which notation is used internally).
Indeed, these two things are not bound to each other. In Pascal, it will be calleable as `baz.foobar' in any case (required by Extended Pascal and Borland Pascal, and the only reasonable thing, anyway, since `$' already has a different meaning in BP and GPC).
For the external declarations, my suggestions is: Procedure Foo; external; (* extern void foo ( void ); *)
(I.e., `external' will convert the name to lower-case, without the module name prefix.)
Procedure FooBar; external name 'FooBar'; (* extern void FooBar ( void ); *)
I've heard Delphi has something like this (`external' and `name'). Is it the same syntax, or what does it look like in Delphi?
Delphi has the same notation, with the same syntax as above, used in the context of *importing* routines from dynamic link libraries (DLLs). Normally the DLL's name will be in-between "external" and "name" -e.g.,
Procedure FooBar; external 'barfoo.dll' name 'FooBar';
I think we could do the same, with the 'barfoo.dll' being optional (is it optional in Delphi as well?). If it's omitted, the compiler will assume the library or object file which contains the routine to be linked by other means (e.g., other `external' statements, `{$L barfoo}' directives, or on the command line).
Furthermore, I think we should drop the `.dll', i.e. just have external 'barfoo', to link `barfoo.dll' on Win32, and `barfoo.so' on Unix, or `barfoo.a' on any system. IOW, it's equivalent to `{$L barfoo}'. Also, we should allow "external 'foo.o'" to link an object file,', "external 'foo.c'" for C files etc. (which is also completely equivalent to the `{$L}' directive).
A slightly similar notation also exists for *exporting* routines from DLLs, in which case it has to be used in a separate "EXPORTS" section at the end of the DLL source (instead of the point where the function is declared) - e.g.,
Library barfoo;
Procedure foobar; Begin // blah, blah End;
Function foofoo : integer; Begin Result := -22; End;
EXPORTS foobar name 'FooBar', foofoo index 1 name 'FooFOO'; // index is optional
Begin End.
I am not sure if (and if so, how) these should be supported by GPC.
I think there should be some way to declare libraries in GPC, but we haven't made any design plans for them yet. Also I suppose they'll not be implemented too soon, since there are more urgent things to do, and it's possible (already now) to build libraries with a little bit of extra work, i.e. declare the public routines with `asmname' (later perhaps `name') directives, compile them with `-c', and build a library of them (with `ar' for static libraries and `gpc -shared' for dynamic ones).
The problem I see with the syntax above is that the external name declaration is at the end. I doubt whether GPC can could with that well since AFAIK it expects to know the external name when it compiles a routine. Perhaps it could use a temporary name while compiling the routine, and declare the real external name as an alias of that temporary name later, but I'm not too sure if that's possible.
If that's not possible, then perhaps a GPC library could look somewhat like a unit, i.e.
library foo;
interface
procedure foobar; name 'FooBar';
implementation
procedure foobar; begin end;
end.
This would not be so much different from what we have already, and therefore probably be easier to realize.
Note: Identifiers exported in this way are case-sensitive when you want to import the DLL functions with the "name" declaration. This is not a Delphi thing but a Win32 thing, so GPC does not need to (and probably should not) seek to copy that behaviour.
`asmname' currently is case-sensitive, and so will `name' be. In order to interface to C code, we don't actually have another choice, because C identifiers are case-sensitive.
In any case, AFAIK, DLLs are only relevant to OS/2 and Win32, so this may not be an issue of serious concern.
They're only called "DLL" on OS/2 and Win32, but dynamic libraries exist on any platform I know except DJGPP (and perhaps EMX for Dos?).
Besides, I don't think we should make a distinction between static and dynamic libraries as far as the program directives are concerned, i.e. let "external 'foobar'" link foobar.dll, foobar.so or foobar.a, whichever is appropriate for the target system and exists (see above). In fact, one can (already now) use the `-static' switch to link the static versions of all libraries rather than the dynamic ones, without changing anything in the source.
Frank
Frank Heckenbach frank@fjf.gnu.de wrote:
[...]
Delphi has the same notation, with the same syntax as above, used in the context of *importing* routines from dynamic link libraries (DLLs). Normally the DLL's name will be in-between "external" and "name" -e.g.,
Procedure FooBar; external 'barfoo.dll' name 'FooBar';
I think we could do the same, with the 'barfoo.dll' being optional (is it optional in Delphi as well?). If it's omitted, the compiler will assume the library or object file which contains the routine to be linked by other means (e.g., other `external' statements, `{$L barfoo}' directives, or on the command line).
Yes, that is more or less what Delphi does as well.
Furthermore, I think we should drop the `.dll', i.e. just have external 'barfoo', to link `barfoo.dll' on Win32, and `barfoo.so' on Unix, or `barfoo.a' on any system. IOW, it's equivalent to `{$L barfoo}'. Also, we should allow "external 'foo.o'" to link an object file,', "external 'foo.c'" for C files etc. (which is also completely equivalent to the `{$L}' directive).
Sounds mostly okay - except that with Win32, a DLL does not need to have the extension '.dll' (for example, Win32 device drivers are just DLLs with the same interface, and with the extension '.drv' ). A Win32 DLL can have any extension, or no extension at all. Thus it might be that the extension will need to be specified. On the other hand, I suppose that perhaps GPC can presume the extension '.dll' unless another extension is suppled. However, how do you then deal with a case where someone has written a DLL but does not want to give it any extension?
[Libraries]
The problem I see with the syntax above is that the external name declaration is at the end. I doubt whether GPC can could with that well since AFAIK it expects to know the external name when it compiles a routine. Perhaps it could use a temporary name while compiling the routine, and declare the real external name as an alias of that temporary name later, but I'm not too sure if that's possible.
If that's not possible, then perhaps a GPC library could look somewhat like a unit, i.e.
library foo;
interface
procedure foobar; name 'FooBar';
implementation
procedure foobar; begin end;
end.
This would not be so much different from what we have already, and therefore probably be easier to realize.
That sounds like a reasonable compromise. This will not be BP or Delphi-compatible, but it is arguably more consistent to do it this way, and this will also make it trivial to convert a UNIT into a library (something that is not so straightforward with Delphi).
Best regards, The Chief -------- Dr. Abimbola A. Olowofoyeku (The African Chief) Email: laa12@keele.ac.uk Homepage: http://ourworld.compuserve.com/homepages/African_Chief/ Author of: Chief's Installer Pro v5.00 for Win32 ftp://ftp.simtel.net/pub/simtelnet/win95/install/chief500.zip
The African Chief wrote:
Sounds mostly okay - except that with Win32, a DLL does not need to have the extension '.dll' (for example, Win32 device drivers are just DLLs with the same interface, and with the extension '.drv' ). A Win32 DLL can have any extension, or no extension at all. Thus it might be that the extension will need to be specified. On the other hand, I suppose that perhaps GPC can presume the extension '.dll' unless another extension is suppled. However, how do you then deal with a case where someone has written a DLL but does not want to give it any extension?
Let GPC first search for the name 'foo' as given, second for 'foo.dll' or 'libfoo.so' (depending on the OS) and last for 'libfoo.a'.
[Libraries]
That sounds like a reasonable compromise. This will not be BP or Delphi-compatible, but it is arguably more consistent to do it this way, and this will also make it trivial to convert a UNIT into a library (something that is not so straightforward with Delphi).
I agree - hoping that it will not be this particular BP/Delphi compatibility issue people will stumble about. ;-)
Peter
Peter Gerwinski peter@gerwinski.de wrote:
Sounds mostly okay - except that with Win32, a DLL does not need to have the extension '.dll' (for example, Win32 device drivers are just DLLs with the same interface, and with the extension '.drv' ). A Win32 DLL can have any extension, or no extension at all. Thus it might be that the extension will need to be specified. On the other hand, I suppose that perhaps GPC can presume the extension '.dll' unless another extension is suppled. However, how do you then deal with a case where someone has written a DLL but does not want to give it any extension?
Let GPC first search for the name 'foo' as given, second for 'foo.dll' or 'libfoo.so' (depending on the OS) and last for 'libfoo.a'.
Perhaps we are talking at cross-purposes here! The Win32 problem will occur not a compile or link time, but at runtime, when the program is trying to link to the DLL. I am not sure whose job it is to search for the DLL at this point - whether it is the compiler's job or the OS (I suspect that it is the job of the OS which should then raise an exception if it cannot find the DLL).
Best regards, The Chief -------- Dr. Abimbola A. Olowofoyeku (The African Chief) Email: laa12@keele.ac.uk Homepage: http://ourworld.compuserve.com/homepages/African_Chief/ Author of: Chief's Installer Pro v5.00 for Win32 ftp://ftp.simtel.net/pub/simtelnet/win95/install/chief500.zip
The African Chief wrote:
Perhaps we are talking at cross-purposes here! The Win32 problem will occur not a compile or link time, but at runtime, when the program is trying to link to the DLL. I am not sure whose job it is to search for the DLL at this point - whether it is the compiler's job or the OS (I suspect that it is the job of the OS which should then raise an exception if it cannot find the DLL).
As far as I have understood it, the compiler places the information in the executable which dynamic library it wishes to be linked against. The OS then looks up that library and does the linking. This means that GPC must find out the actual name of the library (which implies to decide whether it is a `.dll' or an `.so' file), and it is the job of the OS to find a corresponding file when the program is run.
Peter