Я написал функцию 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 без копирования?
buffer = (c_void_p * len(vs))(*vs)
швы для копирования данных. Можете ли вы записать значения обратно в vs
после вызова lib.SortInPlace(buffer)
? Было бы обходным путем.
@rocksportrocker - это то, чего я ожидаю избежать, поскольку это может быть неэффективным.
@ead Понятно. Это оооочень грустно ...
Вы почти наверняка можете получить указатель ctypes из массива (не списка), а затем изменить данные в этом массиве
Вы не можете. См., Например, stackoverflow.com/a/47008303/5769463, чтобы узнать, как можно обрабатывать такие случаи. Поскольку данные в списке не являются непрерывным массивом значений типа int.