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;
Advertisement
Answer
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]