Looking at the MicroHs source code, it has listings of C functions with their signatures, such that they can be used in Haskell's FFI:
* The types are
* V void name(void)
* i int name(void)
* I value_t name(voi)
* IV void name(value_t)
* II value_t name(value_t)
* IIV void name(value_t, value_t)
* III value_t name(value_t, value_t)
* DD flt_t name(flt_t)
* Pi int name(void*)
* PI value_t name(void*)
* PP void* name(void*)
* iPi int name(int, void*)
* PPI value_t name(void*, void*)
* PPP void* name(void*, void*)
and then
{ "log", (funptr_t)log, FFI_DD },
{ "exp", (funptr_t)exp, FFI_DD },
[...]
{ "fgetc", (funptr_t)fgetc, FFI_Pi },
{ "fputc", (funptr_t)fputc, FFI_iPi },
I am wondering whether such a table can't be generated automatically?
The C compiler knows about the ABIs on my system, so if it has compiled the C library, it should also contain information about the signature of e.g. log
and fgetc
.
How would I generate this listing automatically?
I am wondering whether such a table can't be generated automatically? [...] How would I generate this listing automatically?
You can look at how PyQt (using SIP) and PySide generate Python bindings.
PySide uses Shiboken. I'll focus on that.
The C compiler knows about the ABIs on my system
Actually, Shiboken uses clang. You can run its tests using
PYTHONPATH=$PWD/tests/minimalbinding:$PWD/tests/samplebinding:$PWD/tests/otherbinding:$PWD/tests/smartbinding
/usr/bin/ctest
--force-new-ctest-process # this flag is used for the 'make test' target, so I've copied it
--output-on-failure
--stop-on-failure
If you append the -VV
flags, you can see more output.
There is a program called dumpcodemodel
that can be used to extract information from C++ headers:
% ./tests/dumpcodemodel/dumpcodemodel
Usage: ./tests/dumpcodemodel/dumpcodemodel [options] argument(s)
Type system dumper
Parses a C++ header and dumps out the classes found in typesystem XML syntax.
Arguments are arguments to the compiler the last of which should be the header
or source file.
It is recommended to create a .hh include file including the desired headers
and pass that along with the required include paths.
Based on Qt 6.4.2 and LibClang v0.62.
Options:
-h, --help Displays help on commandline options.
--help-all Displays help including Qt specific options.
-v, --version Displays version information.
--verbose Display verbose output about types
--debug Display debug output
-j, --join-namespaces Join namespaces
--std <level> C++ Language level (c++11..c++20, default=c++17)
Arguments:
argument C++ compiler argument
When building Shiboken, make sure you're on the branch that corresponds to your Qt version. I am on Debian 11, so I used the branch for Qt 6.4. See dpkg -l qt6-base-dev
. Otherwise, it's a regular cmake build system, where you can make a separate build directory (used for the commands shown in this post) and execute cmake ..
to do the equivalent of ./configure
.
You can see generated Python bindings in action:
PYTHONPATH=$PWD/tests/minimalbinding
BUILD_DIR=$PWD/..
python3 ../tests/minimalbinding/listuser_test.py -v