0

I'm trying to access an array of ints in DLL from Python. I'm following the guidelines in the ctypes documentation page, but I get Null pointer access exception. My code is:

if __name__ == "__main__":
    cur_dir = sys.path[0]
    os.chdir(cur_dir)
    api = CDLL("PCIE_API")
    PciAgentIndex=POINTER(c_uint32).in_dll(api, "PciAgentIndex")
    print(PciAgentIndex)
    print(PciAgentIndex[0])

And I get:

ValueError: NULL pointer access

When I printing the last line.

When I run this code snippet through Eclipse debugger and check the content attribute of PciAgentIndex I get:

str: Traceback (most recent call last):
  File "C:\Program Files\eclipse\plugins\org.python.pydev_2.7.5.2013052819\pysrc\pydevd_resolver.py", line 182, in _getPyDictionary
    attr = getattr(var, n)
ValueError: NULL pointer access

What am I doing wrong? I'm on Windows and using Python 3.3.2.

1 Answer 1

4

To clarify the difference between a pointer an array, please read the comp.lang.c FAQ, question 6.2: But I heard that char a[] was identical to char *a.

You're creating a pointer from the data in the DLL. Apparently the data starts with either 4 null bytes (32-bit Python) or 8 null bytes (64-bit Python). Use an array instead:

# for a length n array
PciAgentIndex = (c_uint32 * n).in_dll(api, "PciAgentIndex")

You can also cast a function pointer, if you want a pointer:

PciAgentIndex = cast(api.PciAgentIndex, POINTER(c_uint32))

A ctypes data object has a pointer to a buffer for the associated C data. The buffer for a pointer is either 4 or 8 bytes, depending on whether your Python is 32-bit or 64-bit. The buffer for an array is the element size times the length. in_dll is a class method that creates an instance using the data range in the DLL (not just a copy) as its buffer.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! It works with an array now! Anyway, I didn't understand the logic behind this. I don't know how many null bytes there are, but why should that matter?
Thanks, eryksun, you've helped me again :) Anyway, my python is 64bit but is't the C pointer 64bit wide every time? If you say that 8bytes from the pointer are nulls, then the pointer should be wider than 64bit?
Sorry for that I continue to ask questions, but if I'm not wrong PciAgentIndex is, in reality, a pointer to the first element of an array. It should be 64bits wide. In my example I'm initializing a "python pointer" with the address of the PciAgentIndex in the dll. Why is this not working? The "python pointer" and the exported address should be both 64bit wide e.g. the "python pointer" shouldn't be null?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.