RE: problems with FFI including h files
Sad, but very true! And GHC's headers are not very nice in this respect:
panne@jeanluc:~> grep '#define [^ \t][^ \t] ' /usr/lib/ghc-5.03/include/* /usr/lib/ghc-5.03/include/PrimOps.h:#define C 0 /usr/lib/ghc-5.03/include/PrimOps.h:#define R 1 /usr/lib/ghc-5.03/include/PrimOps.h:#define C 1 /usr/lib/ghc-5.03/include/PrimOps.h:#define R 0
Yikes! Fixed, thanks.
panne@jeanluc:~> grep '#define [^ \t][^ \t] ' /usr/lib/ghc-5.03/include/* /usr/lib/ghc-5.03/include/Regs.h:#define R1 (BaseReg->rR1) /usr/lib/ghc-5.03/include/Regs.h:#define R2 (BaseReg->rR2) /usr/lib/ghc-5.03/include/Regs.h:#define F1 (BaseReg->rF1) /usr/lib/ghc-5.03/include/Regs.h:#define F2 (BaseReg->rF2) /usr/lib/ghc-5.03/include/Regs.h:#define F3 (BaseReg->rF3) /usr/lib/ghc-5.03/include/Regs.h:#define F4 (BaseReg->rF4) /usr/lib/ghc-5.03/include/Regs.h:#define D1 (BaseReg->rD1) /usr/lib/ghc-5.03/include/Regs.h:#define D2 (BaseReg->rD2) /usr/lib/ghc-5.03/include/Regs.h:#define L1 (BaseReg->rL1) /usr/lib/ghc-5.03/include/Regs.h:#define Sp (BaseReg->rSp) /usr/lib/ghc-5.03/include/Regs.h:#define Su (BaseReg->rSu) /usr/lib/ghc-5.03/include/Regs.h:#define Hp (BaseReg->rHp)
And so on...
SimonM: What about a "poor man's" namespace, i.e. prefixing every macro, type, etc. with "GHC"/"ghc"? OpenGL, GLUT, GTK, etc. do a similar thing, and although it's a primitive measure, it's very effective.
We really *should* do this, I know. The problem is that it isn't free by a long shot: it'll make .hc files significantly larger, and obfuscate a lot of code. Anyone have any ideas that don't have such a big impact? Cheers, Simon
On 2002-06-03 12:46:19 +0100 Simon Marlow
We really *should* do this, I know. The problem is that it isn't free by a long shot: it'll make .hc files significantly larger, and obfuscate a lot of code. Anyone have any ideas that don't have such a big impact?
Well, what about including FFI headers _before_ the RTS headers? This should solve the problem here (parameter names taken by RTS). The problem would of course persist if someone wants to foreign import an entity called R1 or something like that. The only disadvantage I can think of is that FFI-included headers that rely on RTS definitions would have to be changed to manually include the RTS headers they depend upon - not a common case, IMHO. By the way, I just noticed that using {-# OPTIONS -#include "..." #-} with GHC 5.03 causes the include file to be included _twice_. It's only included once if I specify it on the command line. No double-including in any case with 5.02. Regards, Wolfgang
Anyone have any ideas that don't have such a big impact?
What we did in Hugs (for GreenCard stuff) was create a header file
containing _only_ the things needed by ffi'd code (example attached).
Since it was such a short file, it wasn't too hard to avoid
nameclashes.
This works because the ffi-generated wrappers are very simple and
there's no compiled Haskell code in the same file.
In GHC, I see two options:
1) Compilation generates two C files:
1) A file of ffi wrappers.
These pull in ffi-specified headers, HsFFI.h and maybe a half dozen
function prototypes giving access to GHC runtime internals.
2) A file of compiled Haskell code.
These pull in any GHC headers they like but not ffi-specified headers.
Disadvantage: extra layer of indirection on ffi calls.
2) Restrict ffi to invoking functions not macros.
In this case, GHC generates function prototypes itself based on the
Haskell type and ignores the header files.
If you want to detect mismatches between function prototypes in the C
header file and the GHC-generated prototypes, you could generate a C
file like this:
#include
participants (3)
-
Alastair Reid -
Simon Marlow -
Wolfgang Thaller