python. NET обновление до python 3.7: конструктор массива IntPtr до numpy больше не соответствует заданным аргументам - PullRequest
0 голосов
/ 15 апреля 2020

Следующий код для копирования массива. NET в numpy массив работает в python 2.7.17, но больше не в python 3.7.7:

import clr, numpy
from System import Array, Int32, IntPtr
from System.Runtime.InteropServices import Marshal

n = 10
net_arr = Array.CreateInstance(Int32, n)
for i in range(0, n): net_arr[i] = i

np_arr = numpy.zeros([n], int)
np_ptr = IntPtr.__overloads__[int](np_arr.__array_interface__['data'][0])
Marshal.Copy(net_arr, 0, np_ptr, net_arr.Length)
print(np_arr)

# python2 output:
[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9]

# python3 output:
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    np_ptr = IntPtr.__overloads__[int](np_arr.__array_interface__['data'][0])
TypeError: no constructor matches given arguments

Я знаю, что были некоторые изменения в python типах с 2 на 3, но поиск и игра с конструктором не помогли мне найти решение. Спасибо за любую помощь!

1 Ответ

0 голосов
/ 16 апреля 2020

Обходной путь

(из Python. NET Список рассылки ), что еще быстрее, потому что указатель доступен напрямую и операция копирования исключена:

import ctypes
from System.Runtime.InteropServices import GCHandle, GCHandleType

net_hndl = GCHandle.Alloc(net_arr, GCHandleType.Pinned)
try:
    net_ptr = net_hndl.AddrOfPinnedObject().ToInt64() # ToInt32 gave an Overflow Error
    bufType = ctypes.c_int32 * len(net_arr)
    cbuf    = bufType.from_address(net_ptr)
    np_arr  = numpy.frombuffer(cbuf, dtype=cbuf._type_)
finally:
    if net_hndl.IsAllocated: net_hndl.Free()

Однако, это не объясняет исходную проблему. Как указано в исходном сообщении, это, вероятно, связано с целочисленными изменениями python с версии 2 на 3 и, возможно, в этом сообщении , но я не смог выяснить действительный Конструктор IntPtr .

Если кто-нибудь сможет собрать его, я все равно буду признателен за это!

...