Embedding Python in a MS Windows app

David Bolen db3l at fitlinxx.com
Wed Aug 9 18:23:17 EDT 2000


"Edward K. Ream" <edream at tds.net> writes:

> That's all.  Any comments, especially from Python or SWIG gurus would be
> appreciated.

Just a few incomplete thoughts:

* I actually found the Extending and Embedding documentation
  reasonably good - at least enough to let me construct a project I
  needed when I first started with Python - so I'm not sure about the
  undocumented comments.  Yes, embedding is only afforded a small
  amount of space per-se, but aside from interpreter initialization,
  it's almost identical to extending so you can look at the
  documentation in that light.  Of course more info can never hurt, so
  I think your efforts are definitely in the right direction,
  particularly where they highlight issues for cross-compiler
  compatibility.

  To be honest, in my own embedding work, what I missed up front was
  more information about creating objects in C that worked like
  built-in types or classes.  It seems to me you really have to look
  at the Python source itself to get a better handle on that process.

  Then again maybe I'm just wierd - unintentionally, it turned out my
  first use of Python was to embed it within a multi-threaded C
  application, with real-time communication between the Python and
  native C threads.  At the time I definitely ran into some
  uncertainties with respect to the global interpreter thread lock and
  so on, but it was only later that I realized I probably started at
  the wrong end of the curve :-)

* I don't know about anyone else but I find your use of the terms
  "static" and "dynamic" with respect to linking a bit unintuitive.
  To my mind (and when I typically see them used), static linking is
  just that - it statically binds the library code into your
  executable.  So if you were going to statically link Python into
  your executable you would directly bring the Python interpreter in,
  and would have no dependence on python15.dll.  E.g., it would be
  akin to 'freeze'ing Python.  You are right, it would prevent
  dynamically loading other extension modules that depended on the
  DLL, but it's still one possible approach if you really want to have
  no dependency on external DLLs and you know which modules your
  embedded Python scripts need access to.

  On the other hand, dynamic linking is when you link against an
  import library (e.g., python15.lib) in order to reference an
  external DLL at runtime.  You are dynamically linked to the DLL.

  Dynamically "loading" a DLL at run-time is an entirely different
  beast, and isn't a link time "term" at all, since the linking stage
  has no knowledge of the DLL access at all.
  
  Note also that your comment about "Linking dynamically" (run time
  loading) greatly simplifying link options is certainly true, since
  there aren't any link options involved :-)  But it does make life
  more complicated for the code that has to dynamically load and
  locate the functions to be used.  Even with macros it's a bit of
  work, since you have to deal with potential error conditions that
  can't exist in the other cases (e.g., the inability to even locate
  the function at hand).
  
  I guess the more recent MS "delay loading" support starts to blur
  the line between these approaches even further (I haven't tried
  delay-loading the Python DLL myself yet).

* While run-time loading would permit your application to run without
  a python DLL on the system, if using the Python interpreter is a key
  part of your application, what's the point?  So in general, unless
  the ability to run without Python is crucial, I'd suggest just going
  with the standard dynamic linking approach as the suggested method.

* On points 2-4, while going the SWIG route is certainly doable, it's
  probably also worth noting that for a simple embedded application
  (in my case I really only offered about 6-12 methods, a bunch of
  fixed constant objects and stdout/stderr objects to reroute the
  Python output to my application) it's not really necessary.  It's
  pretty easy to just define your own function table and write your
  functions, particularly if they aren't pre-existing and the reason
  you are writing them is just to interface to Python.  SWIG is fine
  too, but for simple stuff it's just an extra tool to have to have
  around (and it does create some issues by default, as you noted with
  the Py_None return template it uses).

* You've definitely got a point about the FILE structure - it might be
  interesting to see if there was any way to create a shim module that
  might help out (e.g., a DLL built with MSC to work with with Python
  DLL but exporting the typical C RTL functions that use FILE *).

* For Py_None, should that be Py_BuildValue("") and not Py_Build("")?

--
-- David
-- 
/-----------------------------------------------------------------------\
 \               David Bolen            \   E-mail: db3l at fitlinxx.com  /
  |             FitLinxx, Inc.            \  Phone: (203) 708-5192    |
 /  860 Canal Street, Stamford, CT  06902   \  Fax: (203) 316-5150     \
\-----------------------------------------------------------------------/



More information about the Python-list mailing list