Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences in ctypes between Python 2 and 3

I have a working python 2.7 program that calls a DLL. I am trying to port the script to python 3.2. The DLL call seems to work (i.e. there is no error upon calling) but the returned data does not make sense.

Just in case it could be useful: - The call takes three arguments: two int (input) and a pointer to a ushort array (output).

I have tried using both python and numpy arrays without success.

Can anyone enumerate the differences between Python 2.7 and 3.2 respecting ctypes?

Thanks in advance

EDIT

Here is some example code. The DLL is propietary so I do not have the code. But I do have the C header:

void example (int width, int height, unsigned short* pointer)

The python code is:

width, height = 40, 100
imagearray = np.zeros((width,height), dtype=np.dtype(np.ushort))
image = np.ascontiguousarray(imagearray)
ptrimage = image.ctypes.data_as(ct.POINTER(ct.c_ushort))
DLL.example(width, height, ptrimage)

This works in python 2.7 but not in 3.2.

EDIT 2

If the changes in ctypes are only those pointed out by Cedric, it does not make sense that python 3.2 will not work. So looking again at the code, I have found that there is a preparation function called before the function that I am mentioning. The signature is:

void prepare(char *table)

In python, I am calling by:

table = str(aNumber)
DLL.prepare(table)

Is it possible that the problem is due to the change in the Python string handling?

like image 635
Hernan Avatar asked Aug 31 '11 11:08

Hernan


People also ask

Is there a big difference between Python 2 and 3?

Python 3 is definitely more readable, easier to grasp, and popular than Python 2. Python 2 has definitely run out of steam and one should learn Python 2 if and only if some legacy code has been written in Python 2 or if a company needs the developer to migrate the Python 2 code into Python 3.

What is difference between Python 2 and Python 3?

Python 3 is more in-demand and includes a typing system. Python 2 is outdated and uses an older syntax for the print function. While Python 2 is still in use for configuration management in DevOps, Python 3 is the current standard. Python (the code, not the snake) is a popular coding language to learn for beginners.

Is it better to use Python 2 or 3?

Python 3 is a better language and comes with a better set of standard libraries than Python 2. Plus, since 2020, the language and standard libraries are improving only in Python 3.

Which is faster Python 2 or 3?

Python 3.3 comes faster than Python 2.7.


2 Answers

In Python 2.7, strings are byte-strings by default. In Python 3.x, they are unicode by default. Try explicitly making your string a byte string using .encode('ascii') before handing it to DLL.prepare.

Edit:

#another way of saying table=str(aNumber).encode('ascii')
table = bytes(str(aNumber), 'ascii')
DLL.prepare(table)
like image 176
multipleinterfaces Avatar answered Sep 20 '22 08:09

multipleinterfaces


In our case, we had code looking like:

addr = clib.some_function()
data = some_struct.from_address(addr)

This worked in python 2 but not in 3. The reason turned out not to be any difference in ctypes, but rather a change in memory layout that unmasked a bug in the code above. In python 2, the address returned was always (by chance) small enough to fit inside a C int (32-bit), which is the default return type for all ctypes function calls. In python 3, the addresses were almost always too large, which caused the pointer address to become corrupted as it was coerced to int.

The solution is to set the function restype to a 64-bit integer type to ensure that it can accommodate the whole address, like:

clib.some_function.restype = c_longlong

or:

clib.some_function.restype = POINTER(some_struct)
like image 32
Luke Avatar answered Sep 21 '22 08:09

Luke