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;
asked Oct 16, 2019 at 15:57
Tropilio
1,5231 gold badge12 silver badges29 bronze badges
-
1it is explained here: docs.python.org/2/library/ctypes.htmlMEdwin– MEdwin2019年10月16日 16:02:01 +00:00Commented Oct 16, 2019 at 16:02
-
1You'll have to provide more than that (for example the way N is initialized in the library).CristiFati– CristiFati2019年10月16日 16:38:48 +00:00Commented Oct 16, 2019 at 16:38
1 Answer 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]
answered Oct 17, 2019 at 7:08
Mark Tolonen
181k26 gold badges184 silver badges279 bronze badges
Sign up to request clarification or add additional context in comments.
2 Comments
Tropilio
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.Mark Tolonen
@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.Explore related questions
See similar questions with these tags.
default