0

I know that if I have a global variable (let's say a double called N) I can read it using:

from ctypes import c_double, CDLL
c_lib = CDLL('path/to/library.so')
N = c_double.in_dll(c_lib, "N").value

but what if my variable is a pointer? How can I read the contents of the pointer in to a python list?

To be clearer, N is declared in the following way in the shared library:

double N = 420.69;
2
  • 1
    it is explained here: docs.python.org/2/library/ctypes.html Commented Oct 16, 2019 at 16:02
  • 1
    You'll have to provide more than that (for example the way N is initialized in the library). Commented Oct 16, 2019 at 16:38

1 Answer 1

1

Given this (Windows) DLL source:

int ints[10] = {1,2,3,4,5,6,7,8,9,10};
double doubles[5] = {1.5,2.5,3.5,4.5,5.5};

__declspec(dllexport) char* cp = "hello, world!";
__declspec(dllexport) int* ip = ints;
__declspec(dllexport) double* dp = doubles;

You can access these exported global variables with:

>>> from ctypes import *
>>> dll = CDLL('./test')
>>> c_char_p.in_dll(dll,'cp').value
b'hello, world!'
>>> POINTER(c_int).in_dll(dll,'ip').contents
c_long(1)
>>> POINTER(c_int).in_dll(dll,'ip')[0]
1
>>> POINTER(c_int).in_dll(dll,'ip')[1]
2
>>> POINTER(c_int).in_dll(dll,'ip')[9]
10
>>> POINTER(c_int).in_dll(dll,'ip')[10]   # Undefined behavior, past end of data.
0
>>> POINTER(c_double).in_dll(dll,'dp')[0]
1.5
>>> POINTER(c_double).in_dll(dll,'dp')[4]
5.5
>>> POINTER(c_double).in_dll(dll,'dp')[5] # Also UB, past end of data.
6.9532144253691e-310

To get a list, if you know the size:

>>> list(POINTER(c_int * 10).in_dll(dll,'ip').contents)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you Mark! This works perfectly. Do you know by chance if it exists the equivalent in ctypes for a fftw_complex type of variable? Right now I am using a c_double to access a complex variable, and it works, but it doesn't feel right. Anyhow, thanks again for your complete answer.
@FrancescoBoccardo You could use fftw_complex = c_double * 2 to represent that type, or declare class fftw_complex(Structure): _fields_ = ('real',c_double),('imag',c_double) to access it more like a structure.

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.