Want to call C from Python? Use D
atilaoncode.blog
atilaoncode.blog
First there’s PSL ctypes,[1] which is supposedly inferior to cffi to some extent, but hey it comes with your CPython installation, no third-party dep required.
Or you can write a C/C++ extension module.[2] A bit more heavy-handed and there’s a learning curve, but once you’ve done it once or twice it’s really not hard, and it affords you great flexibility.
Also, the solution seems to only cover what’s possible with ctypes already. If don’t need the flexibility there’s little reason to hand roll an extension module. (Not saying ctypes doesn’t have its problems; e.g. when you pass in a wrong number of arguments instead of throwing a TypeError it segfaults.)
Maybe you're thinking of cffi? Cffi does basically what this blog post covers, except without D. It requires a C compiler at some stage in the process, but you can pregenerate during 'build' phase and ship a header snapshot to avoid requiring the C compiler at runtime.
If ctypes can handle the Windows APIs, then I'm convinced it can handle just about anything.
I mean, so does C. Pretty sure that's a "feature". ;)
But yeah, fair point; it's definitely nice when an FFI wrapper is able to actually read the header files and figure out function/type signatures.
In the article, I do this:
``` #include "nanomsg/nn.h" #include "nanomsg/pipeline.h" ```
That's it. I don't think the approaches can be compared.
I can confirm that Atila is a very lazy man. He's always figuring out ways to have his computer do the work for him. He's so successful at avoiding work, people keep giving him more work to do, making him a very hard working lazy man.
One of my earliest programming mentors mused that the reason I might well become a decent programmer was because I was both extremely stubborn and horrifically lazy. He'd observed that I would re-write code until it was the most efficient possible to automate a needed task that could save me time/effort in the future.
Also, the virtue of Impatience seems to be at odds with the principle of YAGNI.
I'm curious to see how this D approach compares, both in workload required to expose and use an API, and the flexibility of the end result. There are a lot of quirks and special syntaxes in Cython to allow for not just interop between C and Python, but also writing C in Python-like syntax mixed with actual Python. This is an area I assume this approach would be lacking.
Regardless, as someone who loves mixing C and Python, this is an encouraging reason to look more at D.
I interfaced CEF to Java in 2000 lines of C++
Simple, easy API. I run CEF in a separate process, and use the Window manager (Linux and Windows) to cause the Chrome windows to overlay the application windows. Standard pipes are used between the controlling process and CEF.
Email me if you are interested. As a ps -- I can use CEF from shell scripts as well. Anything with a C FFI works.
FredW
Such as by using CFFI? Cython's strength, in my opinion, is in the fact that it is its own language resembling both C and Python that compiles to down to C, rather than just an FFI.
> Are your extension modules doing some heavy lifting themselves, or are you using Cython just to handle the glue between the language interface?
I would say the majority of the application logic is written in plain Python, and Cython makes interfacing with it, creating higher level interfaces, and marshaling data far easier than with CFFI or using the C API directly. This is pretty subjective though.
Though most of the C code I write can compile as C++ also. Why write in C then? It's still the lingua franca in microcontroller land... Just want to reuse the code on PC and Embedded Linux, and Python makes high-level testing much nicer.
How is that relevant to a discussion of pybind11?
"if needed" means "needed with any and all C APIs one would be interested in".
(disclaimer: pybind11 contributor)
I personally won't consider using a language for a meaningful project unless it has a decent debugger, and reasonable refactoring; ie. at least find references & rename.
Beef is building on an IDE, which is a refreshing take, but it's still too early.
https://wiki.dlang.org/Editors
Also had really good luck doing D with Spacemacs, but Spacemacs is a hit or miss to setup for me. Other times I just use Sublime Text for the syntax highlighting.
There's some limited debugging support at the generated C code, but this is not sufficient for me.
1. gdc or ldc on Debian. The experience /may/ be different with the dmd repositories, but being external they're of less interest to me.
You can also get soft copies (i.e. mobi, pdf) and the docs as part of the d-apt repository for debian.
Depending on the nature of distribution it is probably just in a different package (or the package maintainer needs yelling at).
Which leads me to wonder why we don't have dmd{,-doc} in Debian now, given it has been ~3 years since the compiler was open sourced. I can't even find an ITP in a quick search :/
dmd -man dman dman
will, of course, open the browser on a page about dman.D in emacs works very well, but you'll have to put some work into it. Spacemacs (https://www.spacemacs.org/) makes the work a little easier, here's my .spacemacs file if anyone is interested https://gitlab.com/snippets/1942930
Using that .spacemacs file you should be able to launch a fully prepped for D! The only other dependencies are a D compiler and DCD (https://github.com/dlang-community/DCD) built and in your PATH. I'd be happy to answer any questions if something doesn't work.
Other IDEs with a languageserver implementation can make use of DLS https://github.com/d-language-server/dls. VSCode and sublime are two I've had good success with.. but I always end up back with emacs ;)
As for a debugger, you can debug any D program with GDB/LLDB (depending on if you compile with dmd/lcd). Then you can use any graphical debugger that uses gdb. Nemiver is my favorite, then there's a few web based ones that are nice: https://www.gdbgui.com/
There is also a D specific IDE which I can't remember the name of which is probably best if you just want something that works (it's pretty lightweight)
(The other half of the puzzle being a tool called autowrap that wraps the resulting D for consumption by Python.)
I'm not sure whether I personally would ever use this, but it's a very interesting exploration of the subject.
Yep!
> (The other half of the puzzle being a tool called autowrap that wraps the resulting D for consumption by Python.)
Correct.
> I'm not sure whether I personally would ever use this, but it's a very interesting exploration of the subject.
Python was an example. Want to call it from C# instead? Same code. Excel? Same code.
No, because I'm not aware of one existing. The only reason I wrote excel-d is because of business reasons.
> actual Excel in the wild and not libreoffice or openoffice
Where I work, and in many many other places, it's all Excel. It's actually the most used programming language in the world. Maybe it shouldn't be, but it is.
Does this work for all revisions of C? iirc cffi works for all of c89 and most of c99
The "code-free" approach here seems to forbid such a fuzzy boundary. Am I wrong?
I've always done this using the bundled Python/C integration path, or when there was too much stuff, use swig.
does this without needing a compiler, by parsing the header files and generating the ctypes wrappers
Wouldn't Nim and Zig also fit the bill?
I don't know how Zig does it, I'd have to look.
I expand on why dpp is the way it is in my DConf 2019 talk: https://www.youtube.com/watch?v=79COPHF3TnE&t=8s
Also there are very easy ways to create Python modules in Nim:
https://robert-mcdermott.gitlab.io/posts/speeding-up-python-...
That's nice, but not the same - users have to intend to write a Python extension in Nim. With autowrap, you can call unmodified D code (and as shown in the blog, C code as well with dpp). That means code that was never meant for consumption from another language can be made available.
Nothing prevents generating a wrapper automatically but 99% of the time that is not very useful. The large majority of Python extension contain Python-specific code to access or return Python objects or act in a pythonic way.
Still not the same.
> Nothing prevents generating a wrapper automatically but 99% of the time that is not very useful. The large majority of Python extension contain Python-specific code to access or return Python objects or act in a pythonic way.
Except, and I cannot stress this enough, at work we're using this to succesfully call into D production code without any Python-specific anything. It just works. The article wasn't even about that, it's about making it work just as seamlessly for C.
Example on wrapping a simple benchmark macro:
- https://github.com/mratsim/weave/blob/052ae40a/experiments/e...
- https://github.com/mratsim/weave/blob/052ae40a/experiments/e...
WinRT is a better model. Basically a higher-level ABI.
And there is no one size fits all.
Kitchen sink languages are my least favorite. Give me something with a tight focus on a problem space.
That didn't quite happen.
> How many languages do we need again? Till you eliminate all tradeoffs in a single language, there would be new ones.