Доступ к глобальному указателю в C из Python с использованием ctypes - PullRequest
0 голосов
/ 16 октября 2019

Я знаю, что если у меня есть глобальная переменная (скажем, двойная с именем N ), я могу прочитать ее, используя:

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

, но что если моя переменная является указателем? Как я могу прочитать содержимое указателя в список Python?

Чтобы быть более понятным, N объявляется в общей библиотеке следующим образом:

double N = 420.69;

1 Ответ

1 голос
/ 17 октября 2019

Исходя из этого (Windows) источника DLL:

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;

Вы можете получить доступ к этим экспортированным глобальным переменным с помощью:

>>> 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

Чтобы получить список, если вы знаете размер:

>>> list(POINTER(c_int * 10).in_dll(dll,'ip').contents)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...