3 ms·
How would you define "good C interoperability"?
by Silhouette 6y ago
How would you define "good C interoperability"?
- api 6y agoCalling C functions with minimal fuss and good performance, which requires C header parsing and linking or DLL loading support. It also requires built in or standard library support for whatever convenience types and functions are needed to make using real C APIs pleasant and as safe as possible. Support for exporting functions and passing function pointers the other way is great too if it can be done. Go with CGo is okay from a usability perspective but performance is poor. I haven't looked much at Rust's implementation so I can't comment. I've also heard Python is not bad.
- Silhouette 6y agoPython was actually the reason I asked the question. There are multiple ways to integrate Python and C, depending on exactly what you want to do. The simplest is to use ctypes, which almost reduces calling C APIs in a DLL/SO to calling a function to load the shared library and then calling the APIs like any other function. The most obvious practical limitation is that ctypes can only infer so much about the required parameter and return types of the C functions from how you call them, so you have to specify the types explicitly in your Python code in any other case. That's no harder than writing a C header file, though, and I expect there is probably a tool somewhere that would automatically generate the corresponding Python/ctypes code for the common use cases. There are a few other warts that aren't quite as intrusive, including some restrictions relating to pointers and some verbose marshalling if you're passing strings around. But overall, it's a very convenient way to call out to C-style APIs from Python code that probably covers 95+% of practical use cases with only minor inconvenience compared to what you'd have written doing everything in either language on its own.
- vips7L 6y agoZig has the best C interop I've ever used. Just a simple import and it figures it out: const c = @cImport({ @cInclude("types.h"); @cInclude("stat.h"); @cInclude("user.h"); });