how to load from Python a dll file written in tcl - python

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!

Related

Python calling and using windows dll’s

I've to ask 1 question about python and dll functions which I'm a bit frustrated about. The question is - Can I load dll functions from windows using python? I heard of Ctype to do that, but I can’t find good tutorials for this. Is there another way to use dll files from windows to get extra functionality?
I want to call some dll to work with mouse events. I used pyautogui but it is not that useful for me. I wonder if python is good for windows applications? I know it runs on Windows however there are good dll function that can provide better functionality for windows then python original libraries. Well that’s my opinion what I think. Anyways, is it worth to work with dlls with python after all? Or I better study C# for that because I love python for simplicity and don’t want to move to C# yet.
Yes you can. The ctypes library is indeed what you need. The official doc is here https://docs.python.org/3/library/ctypes.html .
Loading DLLs pretty straightforward, but calling the functions inside can be a pain depending on the arguments types. Handling old C style error return codes is also cumbersome compared to the exception handling and general low overhead code style in Python.
99% of the time it is way easier and better to use an appropriate existing module that either implements what you need or wraps the appropriate DLL for you. For example search in PyPI which is the central repository of Python expternal modules. That's my advice.

Running python script without installed libraries

I have working Python script using scipy and numpy functions and I need to run it on the computer with installed Python but without modules scipy and numpy. How should I do that? Is .pyc the answer or should I do something more complex?
Notes:
I don't want to use py2exe. I am aware of it but it doesn't fit to the problem.
I have read, these questions (What is the difference between .py and .pyc files?, Python pyc files (main file not compiled?)) with obvious connection to this problem but since I am a physicist, not a programmer, I got totally lost.
It is not possible.
A pyc-file is nothing more than a python file compiled into byte-code. It does not contain any modules that this file imports!
Additionally, the numpy module is an extension written in C (and some Python). A substantial piece of it are shared libraries that are loaded into Python at runtime. You need those for numpy to work!
Python first "compiles" a program into bytecode, and then throws this bytecode through an interpreter.
So if your code is all Python code, you would be able to one-time generate the bytecode and then have the Python runtime use this. In fact I've seen projects such as this, where the developer has just looked through the bytecode spec, and implemented a bytecode parsing engine. It's very lightweight, so it's useful for e.g. "Python on a chip" etc.
Problem comes with external libraries not entirely written in Python, (e.g. numpy, scipy).
Python provides a C-API, allowing you to create (using C/C++ code) objects that appear to it as Python objects. This is useful for speeding things up, interacting with hardware, making use of C/C++ libs.
Take a look at Nuitka. If you'll be able to compile your code (not necessarily a possible or easy task), you'll get what you want.

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).

Embedding Python on Windows: why does it have to be a DLL?

I'm trying to write a software plug-in that embeds Python. On Windows the plug-in is technically a DLL (this may be relevant). The Python Windows FAQ says:
1.Do not build Python into your .exe file directly. On Windows, Python must be a DLL to handle importing modules that are themselves DLL’s. (This is the first key undocumented fact.) Instead, link to pythonNN.dll; it is typically installed in C:\Windows\System. NN is the Python version, a number such as “23” for Python 2.3.
My question is why exactly Python must be a DLL? If, as in my case, the host application is not an .exe, but also a DLL, could I build Python into it? Or, perhaps, this note means that third-party C extensions rely on pythonN.N.dll to be present and other DLL won't do? Assuming that I'd really want to have a single DLL, what should I do?
I see there's the dynload_win.c file, which appears to be the module to import C extensions on Windows and, as far as I can see, it scans the extension file to find which pythonX.X.dll it imports; but I'm not experienced with Windows and I don't quite understand all the code there.
You need to link to pythonXY.dll as a DLL, instead of linking the relevant code directly into your executable, because otherwise the Python runtime can't load other DLLs (the extension modules it relies on.) If you make your own DLL you could theoretically link all the Python code in that DLL directly, since it doesn't end up in the executable but still in a DLL. You'll have to take care to do the linking correctly, however, as pretty much none of the standard tools (like distutils) will do this for you.
However, regardless of how you embed Python, you can't make do with just the DLL, nor can you make do with just any DLL. The ABI changes between Python versions, so if you compiled your code against Python 2.6, you need python26.dll; you can't use python25.dll or python27.dll. And Python isn't just a DLL; it also needs its standard library, which includes extension modules (which are DLLs themselves, although they have the .pyd extension.) The code in dynload_win.c you ran into is for loading those DLLs, and are not related to loading of pythonXY.dll.
In short, in order to embed Python in your plugin, you need to either ship Python with the plugin, or require that the right Python version is already installed.
(Sorry, I did a stupid thing, I first wrote the question, and then registered, and now I cannot alter it or comment on the replies, because StackOverflow's engine doesn't think I'm the author. I cannot even properly thank those who replied :( So this is actually an update to the question and comments.)
Thanks for all the advice, it's very valuable. As far as I understand with some effort I can link Python statically into a custom DLL, provided that I compile other dynamically loaded extensions myself and link them against the same DLL. (I know I need to ship the standard library too; my plan was to append a zipped archive to the DLL file. As far as I understand, I will even be able to import pure Python modules from it.)
I also found an interesting place in dynload_win.c. (I understand it loads dynamic extensions that use Python C API, e.g. _ctypes.) As far as I can see it not only looks for init_ctypes symbol or whatever the extension name is, but also scans the .pyd file's import table looking for (regex) python\d+\. and then compares the found symbol with known pythonNN. string to make sure the extension was compiled for this version of Python. If the import table doesn't have such a symbol or it refers to another version, it raises an error.
For me it means that:
If I link an extension against pythonNN.dll and try to load it from my custom DLL that includes a statically linked Python, it will pass the check, but — well, here I'm not sure: will it fail because there's no pythonNN.dll (i.e. even before getting to the check) or it will happily load the symbols?
And if I link it against my custom DLL, it will find symbols, but won't pass the check :)
I guess I could rewrite this piece to suit my needs... Are there any other such places, I wonder.
Python needs to be a dll (with a standard name) such that your application, and the plugin, can use the same instance of python.
Plugin dlls are already going to expect to be loading (and using python from) a python26.dll (or whichever version) - if your python is statically embedded in your exe, then two different instances of the python library would be managing the same data structures.
If the python libraries use no static variables at all, and the compile settings are exactly the same this should not be a problem. However, generally its far safer to simply ensure that only one instance of the python interpreter is being used.
On *nix, all shared objects in a process, including the executable, contribute their exported names into a common pool; any of the shared objects can then pull any of the names from the pool and use them as they like. This allows e.g. cStringIO.so to pull the relevant Python library functions from the main executable when the Python library is statically-linked.
On Windows, each shared object has its own independent pool of names it can use. This means that it must read the relevant different shared objects it needs functions from. Since it is a lot of work to get all the names from the main executable, the Python functions are separated out into their own DLL.

How can I call a DLL from a scripting language?

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.

Categories

Resources