How can I call a DLL from a scripting language? - python

I have a third-party product, a terminal emulator, which provides a DLL that can be linked to a C program to basically automate the driving of this product (send keystrokes, detect what's on the screen and so forth).
I want to drive it from a scripting language (I'm comfortable with Python and slightly less so with Perl) so that we don't have to compile and send out executables to our customers whenever there's a problem found.
We also want the customers to be able to write their own scripts using ours as baselines and they won't entertain the idea of writing and compiling C code.
What's a good way of getting Python/Perl to interface to a Windows DLL. My first thought was to write a server program and have a Python script communicate with it via TCP but there's got to be an easier solution.

One way to call C libraries from Python is to use ctypes:
>>> from ctypes import *
>>> windll.user32.MessageBoxA(None, "Hello world", "ctypes", 0);

In Perl, Win32::API is an easy way to some interfacing to DLLs. There is also Inline::C, if you have access to a compiler and the windows headers.
Perl XSUBs can also create an interface between Perl and C.

In Perl, P5NCI will also do that, at least in some cases. But it seems to me that anything you use that directly manages interfacing with the dll is going to be user-unfriendly, and if you are going to have a user (scriptor?) friendly wrapper, it might as well be an XS module.
I guess I don't see a meaningful distinction between "compile and send out executables" and "compile and send out scripts".

For Python, you could compile an extension which links to the DLL, so that in Python you could just import it like a normal module. You could do this by hand, by using a library like Boost.Python, or by using a tool such as SWIG (which also supports Perl and other scripting languages) to generate a wrapper automatically.

The Python Py_InitModule API function allows you to create a module from c/c++ functions which can then be call from Python.
It takes about a dozen or so lines of c/c++ code to achieve but it is pretty easy code to write:
https://python.readthedocs.org/en/v2.7.2/extending/extending.html#the-module-s-method-table-and-initialization-function
The Zeus editor that I wrote, uses this appoach to allow Zeus macros to be written in Python and it works very well.

Related

Call a C library from Python

I've found a library which is in C (?), that I want to try from Python:
https://github.com/centaurean/density
I'd like to see if I can store compressed files on disk and decompress them in memory for faster full-file reading times.
I'm new to using external code from Python. How can I create a Python function that uses this library with a little overhead as possible?
(I will work with Windows or Linux)
One way is to compile the library into a dynamic library (.dll on Windows or .so on Linux) and use ctypes (https://docs.python.org/2/library/ctypes.html) to access it.
ctypes provides an easy path into doing exactly this through FFI, with the alternative of using something like SWIG to interface with the python libraries at a much lower layer.
I would recommend generating a little micro-benchmark program to record what the performance is before and after such an experiment, so that you have concrete values to use in choosing if you want to run with ctypes or python-swig code long term over doing something natively in python, which you could trial in c-python or a variant (such as pypy)
Fortunately for you, Python comes with an FFI built-in called ctypes. It works with both Linux and Windows, and there are plenty of tutorials out there to learn how to use it.
Note that you will need to compile the library beforehand into a shared lib (DLL in Windows, SO in Linux).

Bridge between Delphi or C code and Python script

I have a Delphi Win32 program. I want to "expose" somehow app structures and procedures via Python module. E.g. module my_api must expose public items for my app structures/methods. This module must "sit" in memory only.
Then I want, in the same app, to call Python scripts (using Python dll) which can import my_api and call my app methods.
How to do it.
You're asking for two things here, which often go together.
First, you want to extend the Python interpreter, adding types and functions and so forth that Python code can use.
Second, you want to embed the Python interpreter in your app, so it can run Python scripts (which can use your extension modules).
Assuming you want to use CPython (the usual Python interpreter), the tutorial Extending and Embedding the Python Interpreter is part of the docs.
You may want to look at other options that help make the extending side easier—for example, you can use Cython to write the bridge code in a near-Python language instead of C, or Boost.Python to write it in nice C++ that takes care of most of the boilerplate for you, or SWIG to try to generate it automatically, or ctypes to avoid writing a bridge in the first place. But it's worth learning the underlying mechanism first.
You may have heard of Python 4 Delphi by now, and if you haven't you can look it up here. https://code.google.com/p/python4delphi/. There are quite a few tutorials on the internet e,g http://www.atug.com/andypatterns/pythonDelphiTalk.htm

how to load from Python a dll file written in tcl

I have a script written in tcl, that load a dll file. I want to load this file in python. I am not sure if the dll file is written in tcl, but because the tcl file imports it I think it is written in tcl. I have tried to use WinDLL("path_to_dll") but I get that there is no module with the provided name.
The easiest way would be by using the Tkinter package and its built in Tcl interpreter inside your Python Process.
If it is a Tcl extension dll, it makes no real sense to call it from Python without much setup first.
Python and Tcl have substantially different C APIs; there's no reason at all to expect that a binary library written for one would work with the other. It might be possible to write a library that would use the API of whichever library it is loaded into — from the Tcl perspective, this would involve linking against the Tcl stub library so that there's no nasty hard binding to the API — but I don't know how to do that on the Python side of things and it's definitely highly tricky stuff to attempt to do. More practical would be to have one library that contains a language-independent implementation and then two more that bind that API to a particular language (the binding layer could even be automatically generated with a tool like SWIG, though that doesn't address language impedance issues).
Of course, if you're just wanting to write the library from one language and consume it from another, you can do that. A library is just bytes on disk, after all. It does usually tend to be easier to let specialist tools (compilers, linkers) look after writing libraries though; the data format of a library isn't exactly the simplest thing ever!

How to compile Python scripts for use in FORTRAN?

Although I found many answers and discussions about this question, I am unable to find a solution particular to my situation. Here it is:
I have a main program written in FORTRAN.
I have been given a set of python scripts that are very useful.
My goal is to access these python scripts from my main FORTRAN program. Currently, I simply call the scripts from FORTRAN as such:
CALL SYSTEM ('python pyexample.py')
Data is read from .dat files and written to .dat files. This is how the python scripts and the main FORTRAN program communicate to each other.
I am currently running my code on my local machine. I have python installed with numpy, scipy, etc.
My problem:
The code needs to run on a remote server. For strictly FORTRAN code, I compile the code locally and send the executable to the server where it waits in a queue. However, the server does not have python installed. The server is being used as a number crunching station between universities and industry. Installing python along with the necessary modules on the server is not an option. This means that my “CALL SYSTEM ('python pyexample.py')” strategy no longer works.
Solution?:
I found some information on a couple of things in thread Is it feasible to compile Python to machine code?
Shedskin, Psyco, Cython, Pypy, Cpython API
These “modules”(? Not sure if that's what to call them) seem to compile python script to C code or C++. Apparently not all python features can be translated to C. As well, some of these appear to be experimental. Is it possible to compile my python scripts with my FORTRAN code? There exists f2py which converts FORTRAN code to python, but it doesn't work the other way around.
Any help would be greatly appreciated. Thank you for your time.
Vincent
PS: I'm using python 2.6 on Ubuntu
One way or another, you'll need to get the Python runtime on your server, otherwise it won't be possible to execute Python bytecode. Ignacio is on the right track with suggesting invoking libpython directly, but due to Fortran's parameter-passing conventions, it will be a lot easier for you to write a C wrapper to handle the interface between Fortran and the CPython embedding API.
Unfortunately, you're doing this the hard way -- it's a lot easier to write a Python program that can call Fortran subroutines than the other way around.
You don't want any of those. What you should do is use FORTRAN's FFI to talk with libpython and frob its API.

Would it be possible to integrate Python or Perl with Ruby?

Would it be possible to integrate Python (and/or Perl) and Ruby? I've looked at http://www.goto.info.waseda.ac.jp/~fukusima/ruby/python/doc/ and http://code.google.com/p/ruby-perl/ , but they both seem rather outdated.
Has someone generated a Ruby interface for Python's C API?
Edit: Python can be integrated with many other languages according to http://wiki.python.org/moin/IntegratingPythonWithOtherLanguages . However, that list doesn't include Ruby.
My school (Georgia Tech), along with Bryn Mawr and Microsoft Research, are doing a project right now called Pyjama. Basically, it uses the Microsoft DLR to allow you to freely mix Python and Ruby. I haven't tried it, but it sounds pretty cool.
Here's an example from the website. You enter the class in "Python mode". Then it gets compiled, and you run the command in "Ruby mode".
class PythonClass:
def hello(self, value):
print "Python says hello to", value
pc = python_class().new
pc.hello "Ruby"
Which produces "Python says hello to Ruby".
Integrating dynamic languages is one of the goals of the Parrot project. It's a virtual machine that dynamic language compilers target. Once compiled to the same virtual machine, you should be able to used the "object" form in any of the languages no matter the object's source.
The issue at the moment, however, is stabilizing the virtual machine and finishing off the mostly done compilers. However, that's been the state for a long time. :)
You can write extensions for Ruby in C.
So, if Python has a C API, you can write a C extension for Ruby which uses this API.
I know nothing about the Python API or how large of a piece you want to integrate with, but if it is not too big, this could (possibly) give you a way to run Python code from Ruby.
For a research project I wanted to use the fabulous matplotlib that's available for Python. I also found that library that you referred to. However, it doesn't look like something popular and well tested. So I decided to write the script that generated graphs using pure Python and called it from Ruby via popen. That worked very well for me.
It might by possible, but not very practical. It would be significantly easier to port whatever modules you need from one to the other than it would be to embed one of the interpreters within the other.
If you absolutely have to use both languages in a project, your best option would probably the combination of Jython and Jruby, or IronPython and IronRuby. I'm not sure if you could get them to talk to each other, but at the very least you could host them on the same virtual machine.
Another strategy, as used by Facebook, is to expose APIs via Thrift. You define lightweight service APIs and the RPCs are inter-process.

Categories

Resources