LWN.net Logo

Embedding Python in Your C Programs (Linux Journal)

Linux Journal has this article on embedding Python code into C programs. "Including the Python interpreter in your program is extremely simple. Python provides a single header file for including all of the definitions you need when embedding the interpreter into your application, aptly named Python.h. This contains a lot of stuff, including several of the standard headers. For compiling efficiency, it might be nice if you could include only those parts of the interface that you actually intend to use, but unfortunately Python doesn't really give you that option. If you take a look at the Python.h file, you'll see that it defines several important macros and includes a number of common headers that are required by the individual components included later in the file."
(Log in to post comments)

Embedding Python in Your C Programs (Linux Journal)

Posted Dec 30, 2005 22:48 UTC (Fri) by jzbiciak (✭ supporter ✭, #5246) [Link]

Hmmm... I've been toying with the idea of putting a scripting language into my Intellivision emulator. I personally am not a huge fan of Python.

I wonder what language might make a good scripting language? In particular, I'd like to be able to:
  • Expose the machine state as a data structure to the scripting language.
  • Install "trigger" functions on various things that might happen (e.g. a given location's read, written or executed from).
  • Trigger various inputs to the program running in the emulator.
I think any language that allows you to pass around "function references" of some form or another would fit the bill. Anyone out there have any great suggestions? I've contemplated using Perl, just out of familiarity.

Lua

Posted Dec 31, 2005 0:20 UTC (Sat) by ncm (subscriber, #165) [Link]

It's fairly common to embed Lua. For an example use, see Monotone. I have no idea how well it would fit your needs.

Lua

Posted Dec 31, 2005 13:59 UTC (Sat) by ikm (subscriber, #493) [Link]

I have heard several negative opinions about Lua, originated from people who used it for quite some time in major projects and was totally dissatisfied in the end (some even went to modifying it in attempts to make it work better), and no positive ones. But Lua is probably ok for small projects with no massive scripting.

Nowadays, Python seems more to be the "default" choice, and I think it is a good one, actually. Haven't heard negative stuff about it, by the way.

Slang can also be considered -- can't say anything about it though.

Lua

Posted Dec 31, 2005 20:43 UTC (Sat) by Yorick (subscriber, #19241) [Link]

Many of us, not to mention the Lua developers, would be very interested in learning exactly what caused this dissatisfaction. Was it the language design, its implementation, or merely its suitability for the projects it was used for? When it was modified, how and why?

Python is not a bad choice but Lua is more lightweight in resources, making it a frequent choice for scripting in games.

Python developers will usually tell you (and with reason) that instead of embedding Python in your application, you should embed your application in Python. That way it will cooperate nice with other things doing the same, whereas two programs each containing an embedded Python will not. It will also make the user happier since he can import the application as a module into his own projects and therefore solve more problems.

See this for more about extending/embedding Python (and it can be applied to other scripting languages too).

Lua

Posted Jan 2, 2006 23:00 UTC (Mon) by ikm (subscriber, #493) [Link]

Well, I have never tried querying the gory details, so I don't really know; as I described before, I sell for what I bought. But I can remember that in one case the cause of continuous problems was some inherent problems with memory management (dunno if it was implementation or design problem though). Other people were just remembering their Lua experience with shuddering, and I wasn't hearing anything more specific than that. Maybe it was just their problems, not the language ones, I can't really tell.

I fully agree that Lua is much more lightweight than Python -- and as I said, I think Lua may be nice for some small, not complex, lightweight scripting. But I would personally avoid using it when any complex stuff is involved -- just from what I have heard.

Lua

Posted Jan 1, 2006 16:28 UTC (Sun) by oak (guest, #2786) [Link]

Although I like Python as a language more than Lua, when I tried them many
years ago, Lua bindings were easier to do.

My main interest was then the size of the interpreter and Python is *much*
larger than Lua (or e.g. something like Scheme). What are your interests
about the embedded scripting language: just parametrized configuration
parser, or something easily embeddable, small, portable, fast startup,
nice language, lots of ready-made modules/functionality...?

I would also be interested about what these negative opinions about Lua
are. Smells like people didn't think beforehand what they really wanted
from the embedded language. :-)

Squirrel and Ferite

Posted Jan 5, 2006 5:30 UTC (Thu) by atai (subscriber, #10977) [Link]

People considering Lua-like light weight language may consider Squirrel, with a C++/Java like syntax but retaining the Lua-style light-weightness.

Another choice is Ferite

Embedding Python in Your C Programs (Linux Journal)

Posted Dec 31, 2005 0:31 UTC (Sat) by dskoll (subscriber, #1630) [Link]

Tcl is a superb language to embed in C programs. The C API of Tcl is a joy to behold: Orthogonal, complete, well-documented, and extremely well thought-out. I don't know what you think of Tcl as a language, but it's become the de-facto default embedded language in a lot of EDA (Electronic Design Automation) products.

Perl is a more popular language, but its C API is atrocious. Poorly-documented, arcane and prone to easy breakage. I speak from bitter experience.

Embedding Python in Your C Programs (Linux Journal)

Posted Dec 31, 2005 0:32 UTC (Sat) by cventers (subscriber, #31465) [Link]

Once you make sense of the Perl API, it's not so bad. It's quite genius
in some ways... but make no mistake - it looks scary as **** the first
time you look at it.

Embedding Python in Your C Programs (Linux Journal)

Posted Dec 31, 2005 2:37 UTC (Sat) by dskoll (subscriber, #1630) [Link]

Actually, the Perl API looks scary as **** no matter how many times I look at it.

I wrote a program that uses an embedded Perl interpreter, following *EXACTLY* the instructions in the "perlembed" man page. On ancient versions of Linux/Perl (eg, whatever Perl ships with Red Hat 8), it segfaults. On newer versions of Linux/Perl, it works fine. On new versions of Perl on Solaris, it sort-of works. (If I destroy and attempt to recreate the interpreter, it segfaults.)

I posted questions to comp.lang.perl. No-one could diagnose the problem.

OTOH, I've written several fairly large programs that embed Tcl, and found it a joy to work with each time.

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 1, 2006 18:57 UTC (Sun) by busterb (subscriber, #560) [Link]

****, what is that, a pointer to a pointer to a pointer to a pointer ;)

Tcl!

Posted Dec 31, 2005 7:45 UTC (Sat) by davidw (subscriber, #947) [Link]

I'll stand behind the Tcl recommendation too. When I first found the language, I thought it was ok, but when I discovered the C API, I thought "wow, I could do all kinds of things with this" - it's easy! Then I came to appreciate the language itself, as well.

comp.lang.tcl is the place to go to if you have further questions - as well as http://wiki.tcl.tk

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 1, 2006 1:13 UTC (Sun) by sumnerh (guest, #34870) [Link]

Python is an excellent choice. Trigger functions on memory access aren't really going to be supported per se in any embedded language that I know of, but depending on how you handle the memory access from C it's easy to queue up events for the embedded language and/or trigger scripts to run. The other items (e.g. exposing internals in some kind of data structure to be accessed from Python) are very easy.

I've also found Tcl easy enough to embed, but I don't like the language at all.

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 1, 2006 5:32 UTC (Sun) by zblaxell (subscriber, #26385) [Link]

Tcl is nice but it might not be for your project.

One of Tcl's strengths is that all native datatypes have a canonical string representation, including code. This is used in the field for things like single-file applications (database + database library + application, all in one self-modifying cross-platform file) and remote code execution (one company makes a motion controller which contains a network server to which you can send fragments of Tcl code to control industrial machinery).

One of Tcl's weaknesses is that there's no such thing as a reference, and another is that if you're not extremely careful about implied conversions, you might cause all intermediate math results to go through atof() and back. If you want to do a lot of bit-level meddling with the machine state from the scripting language then you need to be careful to avoid implicit string conversions or changes in interpreter state that invalidate cached compiled code. It might be actually be painful to use Tcl in this case--I've done bit-banging code in Tcl, and it can be spectacularly slow unless the coder is careful to avoid those implied string conversions.

Another Tcl weakness is that the language is simple--much simpler than many programmers are used to. There are 11 paragraphs in the Tcl(7) man page describing the entire language syntax, but if you ever miss any trivial detail of any of them, then your program will run, but it will do something different than what you expect--often this involves accidentally executing variables as code in contexts you didn't expect.

In your case, you could store your code either as Tcl strings, or in Tcl procedures (which are still strings but only one word is used to invoke them ;-). From the Tcl C API's point of view, you can convert the strings to Tcl_Obj*, then evaluate the Tcl_Obj* which will compile the string to bytecode and cache the result relatively transparently. The API also has fast-path hooks for calling a named procedure with a vector of arguments from C.

It might be better to expose machine state through a variety of accessor functions rather than as a single Tcl data structure--that way you'll only be converting and/or copying the parts of the machine state you're actually accessing from Tcl. The "Tcl way" of doing that sort of thing is a function like "get_register_state -bx -ax" which returns a list of the contents of the "bx" and "ax" registers in that order (sorry, I forget which CPU the Intellivision uses ;-) or "get_memory_contents 0 1023" which would return a string that could be further processed by "binary scan ...".

Tcl has trigger functions on its own variable accesses. This probably isn't useful in your case, but it's interesting nonetheless.

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 1, 2006 2:05 UTC (Sun) by welinder (guest, #4699) [Link]

Unfortunately the Python developers have a serious I-own-the-world
attitude problem. As a result, python in incompatible with, for example,
autoconf. And they just cannot see the problem in that.

(See, for example, http://sourceforge.net/tracker/index.php?func=detail&...)

Basically, an extension language should not impose constraint that only
one library can fulfill. Guile wants to (or maybe that is "used to")
take over "main" -- that is just not acceptable. Python wants to
control my compilation environment by #defining stuff that changes
libc behaviour -- that is not for you to control!

Perl and python, if I understand things right, even want to control
what compiler you use, so if they were not compiled with the same
compiler and you want to include both, then you are out of luck.

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 1, 2006 2:28 UTC (Sun) by sumnerh (guest, #34870) [Link]

The comment there explains the proper use correctly--make sure you include Python.h before limits.h. You really do need to have the limits defined the same way as during language build to include any embedded scripting language; it's not an "I own the world" thing, but a real technical issue (types need to be the correct size). The alternative would be to marshal/unmarshal all your data when you pass it back and forth between your application and the interpreter, which is clunky and slow--if you're going to do that you may as well run the interpreter in a seperate process and communicate over a socket.

Using different minor versions of the compiler is fine, I haven't tried different major releases but the issues should be the same as for using different majors to build a shared library and a project. Interpreters written in C++/ObjC may be different since the compatibility requirement between compiler versions are often more stringent there.

I've had no problems embedding Python into projects I build with autoconf.

As an earlier comment noted, you can avoid some of these issues by making your app an extension and calling back into it from Python/Perl code rather than vice-versa; whether that makes sense depends on your application.

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 2, 2006 5:13 UTC (Mon) by welinder (guest, #4699) [Link]

With Python you must include Python.h first.
With autoconf you must include config.h first.

Clearly that is not going to happen. You might still get lucky on
any given platform, though.

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 1, 2006 4:46 UTC (Sun) by zblaxell (subscriber, #26385) [Link]

Naturally if you're going to link a library to an application and pass types back and forth, you have to have the same types defined in the same way in both places. That much should be obvious. If there's any possibility of having a choice, both application and library must choose the same way.

It is a little odd that Python wants to change the behavior from the default, but it wouldn't be so odd if Python insisted on having the default while your application contains C-library-behavior-changing #defines.

Unfortunately all libraries impose these kinds of constraints on their calling applications (and even other libraries) to some degree. Libraries that happen to be embeddable scripting language interpreters simply have more constraints than most. They also tend to include a portable runtime library that runs on all the platforms the scripting language does, so they'll include their own layers on top of stdio, GUI frameworks, and so on, all of which just increase the number of points where parameters of the build environment can collide with semantics of the scripting language.

These days the scripting languages also come with the infrastructure to integrate them into application build systems, although often that means "build your application with ScriptLanguageMake" instead of whatever tool you wanted to use. Perl does a lot of source-level preprocessing and (last time I checked) pretty much implements make itself, while Tcl provides almost 200 lines of compiler flag variables that your application needs to be built with.

Auto* in my experience is particularly badly suited for scripting language modules. Last time I tried (which was admittedly many automake versions ago), I had to do things like write C programs whose sole function in life was to execve() a script in the appropriate language to finish the build process.

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 1, 2006 6:42 UTC (Sun) by busterb (subscriber, #560) [Link]

Nah, it's not really that bad. I got my C library working within Python
and building with autotools in a few hours (starting from scratch)
following the info here:

http://www.geocities.com/foetsch/python/swig_linux.htm

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 2, 2006 5:32 UTC (Mon) by welinder (guest, #4699) [Link]

Unfortunately, the code you link to does not work. Things like

_your_extension_la_CPPFLAGS = $(SWIG_PYTHON_CPPFLAGS) -I$(top_srcdir)/src

assume that the compiler used for compiling your project understands
the options that whatever compiler was used to compile swig itself
used.

The C library and the X11 libraries do not impose such constraints.
They just supply a well defined interface [from a C language point
of view, mind you], i.e., .h files, and that's it.

Embedding Python in Your C Programs (Linux Journal)

Posted Jan 2, 2006 10:49 UTC (Mon) by kleptog (subscriber, #1183) [Link]

But it doesn't have to be that way. Python could simply typedef some new types called pyint32, pyint64, pyfloat4, etc and define their interface in those terms. The compiler will then tell the user when there are issues with mismatched types. There's no reason for python to change the defaults for the entire rest of your program.

Especially with the C99 stdint.h, this sort of stuff has become very easy to do.

Embedding Python in Your C Programs (Linux Journal)

Posted Sep 7, 2006 16:53 UTC (Thu) by jacksamuels (guest, #40380) [Link]

A python program is there(in cgi or mod python) .This program must take a Clanguage program as an input and it must be compiled and the output must be written back to some text file(also must be displayed on browser this can be done using html forms).How to do this.Can it be done in cgi or modpython??

Copyright © 2005, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds