How to Use a Dll File from Python

How can I use a DLL file from Python?

For ease of use, ctypes is the way to go.

The following example of ctypes is from actual code I've written (in Python 2.5). This has been, by far, the easiest way I've found for doing what you ask.

import ctypes

# Load DLL into memory.

hllDll = ctypes.WinDLL ("c:\\PComm\\ehlapi32.dll")

# Set up prototype and parameters for the desired function call.
# HLLAPI

hllApiProto = ctypes.WINFUNCTYPE (
ctypes.c_int, # Return type.
ctypes.c_void_p, # Parameters 1 ...
ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_void_p) # ... thru 4.
hllApiParams = (1, "p1", 0), (1, "p2", 0), (1, "p3",0), (1, "p4",0),

# Actually map the call ("HLLAPI(...)") to a Python name.

hllApi = hllApiProto (("HLLAPI", hllDll), hllApiParams)

# This is how you can actually call the DLL function.
# Set up the variables and call the Python name with them.

p1 = ctypes.c_int (1)
p2 = ctypes.c_char_p (sessionVar)
p3 = ctypes.c_int (1)
p4 = ctypes.c_int (0)
hllApi (ctypes.byref (p1), p2, ctypes.byref (p3), ctypes.byref (p4))

The ctypes stuff has all the C-type data types (int, char, short, void*, and so on) and can pass by value or reference. It can also return specific data types although my example doesn't do that (the HLL API returns values by modifying a variable passed by reference).


In terms of the specific example shown above, IBM's EHLLAPI is a fairly consistent interface.

All calls pass four void pointers (EHLLAPI sends the return code back through the fourth parameter, a pointer to an int so, while I specify int as the return type, I can safely ignore it) as per IBM's documentation here. In other words, the C variant of the function would be:

int hllApi (void *p1, void *p2, void *p3, void *p4)

This makes for a single, simple ctypes function able to do anything the EHLLAPI library provides, but it's likely that other libraries will need a separate ctypes function set up per library function.

The return value from WINFUNCTYPE is a function prototype but you still have to set up more parameter information (over and above the types). Each tuple in hllApiParams has a parameter "direction" (1 = input, 2 = output and so on), a parameter name and a default value - see the ctypes doco for details

Once you have the prototype and parameter information, you can create a Python "callable" hllApi with which to call the function. You simply create the needed variable (p1 through p4 in my case) and call the function with them.

Python import dll

You've tagged the question ctypes and so it sounds like you already know the answer.

The ctypes tutorial is excellent. Once you've read and understood that you'll be able to do it easily.

For example:

>>> from ctypes import *
>>> windll.kernel32.GetModuleHandleW(0)
486539264

And an example from my own code:

lib = ctypes.WinDLL('mylibrary.dll')
#lib = ctypes.WinDLL('full/path/to/mylibrary.dll')
func = lib['myFunc']#my func is double myFunc(double);
func.restype = ctypes.c_double
value = func(ctypes.c_double(42.0))

Loading dll using Python Ctypes

Make sure your compiler and version of Python are both 32-bit or both 64-bit. You can't mix, which is the cause of OSError: [WinError 193] %1 is not a valid Win32 application.

Next, make sure to compile as a C program and not C++. That's the cause of the name mangling mention in your answer.

Example (note compiler is for x86 not x64:

C:\>cl /LD /W4 test.c
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.61030 for x86
Copyright (C) Microsoft Corporation. All rights reserved.

test.c
Microsoft (R) Incremental Linker Version 11.00.61030.0
Copyright (C) Microsoft Corporation. All rights reserved.

/out:test.dll
/dll
/implib:test.lib
test.obj
Creating library test.lib and object test.exp

Now use a 32-bit Python:

C:\>py -2
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:42:59) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> lib = CDLL('test')
>>> lib.sum(2,3)
5

If you compile as C++, you can still call functions by exporting them as C, which prevents the C++ name mangling:

//test.cpp
extern "C" __declspec(dllexport) int sum(int a, int b) {
return a + b;
}

Accessing DLL function using ctypes

You're on the right track but got a bit confused along the way - taking a code file and giving it a .dll extension isn't enough to turn it into a DLL, you do still need to compile it. Your linker is telling you that it doesn't know how to parse your file:

myfunctionsDLL2.dll : warning LNK4048: Invalid format file; ignored

because it only knows how to parse real executables.


You should rename your second code file (the one you named my_functionsDLL2.dll) back to my_functions.c - and compile it the same way you did the first time. But this time, because you added __declspec(dllexport) to your function definition, your compiler (cl.exe) will know that these functions are meant to be exported from the DLL and will export them, making them available through ctypes.

How use correctly a .dll file in python on linux and mac

As hoefling explained, *.dll libraries are only for Windows.
At the site you've specified, there already are libraries built for and Linux.

Sample Image

The static lib propa64.a definitely should work on Linux, and I guess if it's for x86 64-bit platform, it should also work on MacOS.



Related Topics



Leave a reply



Submit