user2899492
user2899492

Reputation: 21

Python ctypes Passing a Pointer and getting null pointer access

I'm using Python and ctypes to use a .dll supplied by a company for the use with a load cell amplifier. I manage to get a reading with their software, but I can't get my Python code to work. The company is ME-MessSysteme, and the amplifier is the GSV-2 (Manual Here).

The company's description of the function:

C: int GSVread ( int no, double *ad )

Taken from here, page 44. Sorry, but the guide is in German.

I'm getting a response from the amplifier after the activate function, but when I use the GSVread function, I can't get the result. I tried to pass a pointer to a double variable as I understand it returns the value to it. When I try to access the contents I get a "ValueError: NULL pointer access".

import ctypes
ret = ctypes.POINTER(ctypes.c_double)()
print(ret)
gsv = ctypes.cdll.LoadLibrary("DLLs_SENSOLYTICS/MEGSV.dll")
print(gsv.GSVactivate(7))
print(gsv.GSVstartTransmit(7))
print(gsv.GSVread(7, ret))
print(ret.contents)

7 indicating the COM port number.

Thank you all in advance!

****UPDATE***** Following on Dan's answer, the code that works is below:

    d = ctypes.c_double()
    ret = ctypes.byref(d)

    gsv = ctypes.cdll.LoadLibrary("DLLs_SENSOLYTICS/MEGSV.dll")
    print(gsv.GSVactivate(7, ctypes.c_long(256)))
    gsv.GSVflushBuffer(7)
    print(gsv.GSVstartTransmit(7))
    time.sleep(1)
    gsv.GSVread(7, ret)
    print(d)

Upvotes: 2

Views: 1932

Answers (1)

Dan D.
Dan D.

Reputation: 74655

You need to create two objects one the double and the other the pointer to the double:

>>> d = ctypes.c_double()
>>> ret = ctypes.pointer(d)
>>> ret.contents
c_double(0.0)

This can also be written as:

ret = ctypes.pointer(ctypes.c_double())

Which is oddly similar to:

ret = ctypes.POINTER(ctypes.c_double)()

The documentation states that ctypes.byref is a faster ctypes.pointer that doesn't actually allocate a real ctypes.pointer object so it can only be used to be be passed to a reference as an argument to a C function.

To use it one has to keep a direct reference to the double to be able to access the result as ctypes.byref objects do not have a contents property.

d = ctypes.c_double()
ret = ctypes.byref(d)

Upvotes: 2

Related Questions