Как напрямую получить доступ к указателю списка Python для перехода в функцию C?

Я написал функцию C с именем SortInPlace, которая сортирует целочисленный массив на месте. Теперь я хочу вызвать его из Python. Ниже приводится основная часть моего кода:

def sort_in_place(vs):
    buffer = (c_void_p * len(vs))(*vs)
    lib.SortInPlace.argtypes = [c_void_p]
    lib.SortInPlace.restype = None
    lib.SortInPlace(buffer)
    print "buffer: ", buffer

vs = [3,2,1]
sort_in_place(vs)
print "vs: ", vs

Однако результат оказывается

buffer: 1,2,3
vs: 3,2,1

Я распечатал адресbuffer и vs, которые показывают, что у них разные адреса памяти. Таким образом, buffer сортируется по месту, а vs не затрагивается.

Я также пытался использовать array для преобразования vs в указатель:

from array import array
a = array('l',vs)

# however, their addresses are also different
print hex(id(vs))
print hex(a.buffer_info()[0])

В обоих случаях исходный vs всегда скопировано для нового буфера памяти. Мой вопрос: как я могу напрямую создать буфер из адреса объекта списка Python без копирования?

Вы не можете. См., Например, stackoverflow.com/a/47008303/5769463, чтобы узнать, как можно обрабатывать такие случаи. Поскольку данные в списке не являются непрерывным массивом значений типа int.

ead 05.09.2018 09:46
buffer = (c_void_p * len(vs))(*vs) швы для копирования данных. Можете ли вы записать значения обратно в vs после вызова lib.SortInPlace(buffer)? Было бы обходным путем.
rocksportrocker 05.09.2018 09:48

@rocksportrocker - это то, чего я ожидаю избежать, поскольку это может быть неэффективным.

HanXu 05.09.2018 10:33

@ead Понятно. Это оооочень грустно ...

HanXu 05.09.2018 10:35

Вы почти наверняка можете получить указатель ctypes из массива (не списка), а затем изменить данные в этом массиве

DavidW 05.09.2018 16:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
145
0

Другие вопросы по теме