6 comments

[ 3.9 ms ] story [ 35.2 ms ] thread
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.)
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.

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.

Reminds me of boost.python, which is also macro-heavy.
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.

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.