Modification to foreign import/export

Marcin 'Qrczak' Kowalczyk qrczak at knm.org.pl
Sat Feb 10 10:56:10 EST 2001


Nobody answered, so perhaps everybody agrees :-)

Sat, 03 Feb 2001 00:14:56 +1100, Manuel M. T. Chakravarty <chak at cse.unsw.edu.au> pisze:

> Re (2): In Java, we obviously want to use qualified names
>   (like "java.lang.foo"), but in the case of dynamic
>   libraries and C calls it is less clear what the syntax
>   should look like.  "gtk: gtk_new_window" to specify that
>   the dynamic library "gtk" (on Unix that would happen by
>   loading "libgtk.so") has to be loaded to call the function
>   "gtk_new_window"?

On Linux it is not specified which functions are taken from which
library - everything is linked into a flat global namespace. Similarly
for #included files (but this is during compilation, not linking,
and thus can be different for each module).

Is it true for Windows and other platforms too? Or do some platforms
require to tell from which libraries individual functions are taken?

If not, we could use this fact and specify the C library in a separate
foreign declaration rather than together with each function.

This has the advantage that when the library name is #ifdefed, the
conditional needs not to be repeated for each function. Similarly
for #included header names.

A disadvantage is that linking using dlopen/dlsym or equivalent
(in interpreted environments) is problematic, because then you must
know the library of each function. It still can be done; we assume
that a single module will not import two identically named functions
from different libraries, so if more than one library is specified,
an interpreter can try each of them for each function.

For C++ the external name would contain the namespace, but not the
library nor header.

> Is it reasonable to require that only foreign declarations of
> a *single* foreign language are allowed per Haskell module?

We can give up the irrelevance of the order of declarations (which does
not apply for regular imports anyway - they must be at the top of the
module, before all local definitions). We can have some declaration
specifying the context of *following* foreign declarations. Another
such declaration can change the context later in the module.

In this case we have both the generality and convenience. The language,
calling convention, header files, and libraries would be moved there.
My discussion above is pointless: we specify the library name once,
but logically it applies to each individual function.

Here is a concrete proposal:

foreign language "c",
#if HAVE_NCURSES_CURSES_H
    include "<ncurses/curses.h>",
#elif HAVE_CURSES_H
    include "<curses.h>",
#else
#error Where is curses.h?
#endif
    library "ncurses"

The set of meaningful pseudokeywords ('include' and 'library' above)
depends on the 'language' which is mandatory and must be specified
first. Multiple headers/libraries/etc. can be specified as separate
include/library/etc. clauses.

I hope all interesting parameters in the future will fit in the syntax
of keyword/string pairs, with the string being optional (some keywords
are just boolean switches), or perhaps with multiple strings separated
by spaces (multiple headers/libraries could be specified that way).

The calling convention is specified thus:
foreign language "c", include "<whatever.h>", stdcall
and removed from individual functions.

All information normally found in the C header must be duplicated by
other means, because the header is used only optionally to check
the call with the prototype, and physical linking with the function
can be done without cooperation with the C compiler.

Header and library paths are specified by compiler's commandline
options as usual.

-- 
 __("<  Marcin Kowalczyk * qrczak at knm.org.pl http://qrczak.ids.net.pl/
 \__/
  ^^                      SYGNATURA ZASTÊPCZA
QRCZAK





More information about the FFI mailing list