How do you bind a language (python, for example) to another (say, C++)?

I'm far from a python expert but I hear this one all the time, about its C/C++ bindings. How does this concept work, and how does Python (and Java) bind to C-based APIs like OpenGL? This stuff has always been a mystery to me.


Interpreters Written in C89 with Reflection, Who Knew?


I have a feeling you are looking for an explanation of the mechanism and not a link to the API or instructions on how to code it. So, as I understand it . . .

The main interpreter is typically written in C and is dynamically linked. In a dynamically linked environment, even C89 has a certain amount of reflective behavior. In particular, the dlopen(3) and dlsym(3) calls will load a dynamic (typically ELF) library and look up the address of a symbol named by a string. Give that address, the interpreter can call a function. Even if statically linked, the interpreter can know the address of C functions whose names are compiled into it.

So then, it's just a simple matter of having the interpreted code tell the interpreter to call a particular native function in a particular native library.

The mechanism can be modular. An extension library for the interpreter, written in the script, can itself invoke the bare hooks for dlopen(3) and dlsym(3) and hook up to a new library that the interpreter never knew about.

For passing simple objects by value, a few prototype functions will typically allow various calls. But for structured data objects (imagine stat(2)) the wrapper module needs to know the layout of the data. At some point, either when packaging the extension module or when installing it, a C interface module includes the appropriate header files and in conjunction with handwritten code constructs an interface object. This is why you may need to install something like libsqlite3-dev even if you already had sqlite3 on your system; only the -dev package has the .h files needed to recompile the linkage code.

I suppose we could sum this up by saying: "it's done with brute force and ignorance". :-)


The main general concept is known as FFI, "Foreign Function Interface" -- for Java it's JNI, for Python it's the "Python C API", for Perl it's XS, etc, etc, but I think it's important to give you the general term of art to help you research it more thoroughly.

Given a FFI, you can write (eg) C programs that respect it directly, and/or you can have code generators that produce such C code from metainformation they receive and/or introspect from code written in other languages (often with some help, eg, to drive the SWIG code generator you typically decorate the info that's in a .h C header file with extra info that's SWIG-specific to get a better wrapper).

There are also special languages such as Cython, an "extended subset" of Python that's geared towards easy generation of FFI code while matching much of Python's syntax and semantics -- may often be the easiest way for mostly-Python programmers to write a Python extension module that compiles down to speedy machine code and maybe uses some existing C-callable libraries.

The ctypes approach is different from the traditional FFI approaches, though it self-describes as a "foreign function library for Python" -- it relies on the foreign code being available in a DLL (or equivalent, such as an .so dynamic library in Linux), and generates and executes code at run-time to reach into such dynamically loaded C code (typically all done via explicit programming in Python -- I don't know of ctypes wrappers based on introspection and ctypes-code generation, yet). Handy to avoid having to install anything special for simple tasks of accessing existing DLLs with Python, but I think it doesn't scale up as well as the FFI "linker-based" approaches (as it requires more runtime exertion, etc, etc). I don't know of any other implementation of such an approach, targeting other languages, beyond ctypes for Python (I imagine some do exist, given today's prevalence of DLL and .so packaging, and would be curious to learn about them).


Generally these languages have a way to load extensions written in C. The Java interface is called JNI (Java Native Interface). Python has comprehensive documentation about its extension interface.

Another option for Python is the ctypes module which allows you to work with dynamically loadable C libraries without having to write custom extension code.

链接地址: http://www.djcxy.com/p/96832.html

上一篇: 如何让NDK调试在Android Studio中工作?

下一篇: 你如何将一种语言(例如Python)绑定到另一种语言(比如说C ++)?