[C2hs] Function Hooks and Calling Convention

Thomas DuBuisson thomas.dubuisson at gmail.com
Mon Sep 21 20:45:53 EDT 2009

Playing with function hooks, I've found two issues that draw my ire.
FYI, this is more of a partial experience report than a question.

For an example, let us discuss the kernel function
"pci_register_driver", which is actually a macro and thus not handled
by the function hooks.  The first step in fixing this is a CPP
    inline int pci_register_driver2(pci_dev_t d)

So I'd call this experience number 1 - it is entirely possible to
automatically generate wrapper functions for macros ( {#macro ...}? or
even {#fun ...} handling macros too).  Perhaps there's not enough
interest for anyone to make this change but I expect this to come up
more and more often.  I'll note that this is very similar to the issue
of importing pure macros (macros that don't wrap a function call),
which would be a nice feature.

I can now write the hook and c2hs will parse things ok:

    {#fun pci_register_driver2 as ^
        {id  `PCIDriver'
        } -> `Int' id#}

generating a foreign import:

    foreign import ccall safe "pci.chs.h pci_register_driver2"
      pciRegisterDriver'_ :: ((PCIDriver) -> (IO CInt))

And all seems well... except that I'm aiming to use this in
interfacing with the Linux kernel.  The generated *.chs.h file
will/must be compiled into an object file using the Linux build
system, which defaults to a regparm3 calling convention.  Why does
c2hs automatically assume its a ccall?  I could really use an
opportunity to insert an alternate convention.

In the end the solution I have is to manually write the above C
section and the foreign import call using a regparm3 calling
convention.  This isn't to say c2hs isn't used - its still hugely
helpful (so long as the headers remain easy to convert to ANSI C), but
just my quick experience.


More information about the C2hs mailing list