
Show HN: Autowrap C functions at runtime for the Python/C API - orangeduck
https://github.com/orangeduck/PyAutoC
======
Erwin
What do you mean "runtime" ? You have to compile some C code with macros to
wrap a unique type signature for each function you want to wrap, so this seems
to require a compilation step unlike e.g. ctypes which is a runtime FFI. If
there's a compilation step, why wouldn't I just want to use Pyrex/Cython which
let me write this:

    
    
        def py_do_something(float a, float b):
           return c_do_something(a,b)
    

while, during the Pyx -> .c compilation step, taking care of all the C API
plumbing (refcounting, initializing a module structure, type checking etc.)

~~~
orangeduck
By runtime I mean that the functions which are avaliable are registered at
runtime - rather than being statically wrapped or converted by some previous
tool in the toolchain. Sure, there is some macro stuff going on, but if you
were to evaluate the macro stuff by hand you could even use PyAutoC to
register C functions truly at run-time using dlopen.

A clear example of why this is useful is shown in the demo about overwriting
__getattr__ etc. A static tool will just generate N number of getters and
setters.

Pyrex/Cython are both pretty cool. I developed this for helping me with
embedding python on an existing C codebase. Something those two things can't
do. Similarly ctypes is great for doing it the other way around but doesn't
work well for embedding and also doesn't do the automatic conversion so well.

~~~
unwind
For my money, something that looks like a C API with very obviously impossible
things going on (passing "naked" names of primitive types like int and float)
makes my personal WTF-o-meter go to eleven immediately.

I (of course) had to start reading the code to figure out what was going on,
and saw that what looks like a function call is in fact a macro. That explains
the "how" but (again, for me) it really doesn't come close to making it feel
natural.

C code should look like C code, and you can't write a function that takes a
bare "int" as an argument.

~~~
orangeduck
Fair enough, I agree that it isn't the prettiest or most natural of code but
it isn't any "magic" too far beyond convention. Without C++ templates this is
the only way to achieve certain things - and is fairly standardized.

See va_args for an example of naked types being passed in the standard
library. Really it is not much different from the fact you have to pass a
format string to printf.

~~~
unwind
That's true, I had forgotten about va_arg()'s use of naked types. I do think
the standard library has a bit more license to do weird stuff, and it's fairly
well-known that va_* can be macros.

