Я звоню в NASM 64 dll из ctypes;он включает в себя обратный вызов функции SciPy integrate.dblquad.Обратный вызов получает указатель на массив из двух двойных и возвращает указатель на массив из двух двойных.Функция обратного вызова выполняется правильно и показывает правильные результаты в Python, но у меня возникают проблемы с возвратом указателя обратно в NASM.
Я разместил этот вопрос 12 мая в виде вопроса ctypes на Какой тип указателя верен для обратного вызова ctypes? .Я получил ответ на языке C с решением, которое не могу использовать в NASM.Я надеюсь, что кто-то может помочь с тем, как это может работать в NASM, а не C.
Вот часть кода ctypes, который вызывает dll и выполняет обратный вызов:
CA_data1 = (ctypes.c_double * len(data1))(*data1)
CA_data2 = (ctypes.c_double * len(data2))(*data2)
hDLL = ctypes.WinDLL("C:/NASM_Test_Projects/SciPy_Test/SciPy_Test.dll")
CallName = hDLL.Main_Entry_fn
CallName.argtypes = [ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_longlong)]
CallName.restype = ctypes.c_double
ret_ptr = CallName(CA_data1,CA_data2,length_array_out,lib_call)
Воткод обратного вызова:
from scipy.integrate import dblquad
import ctypes
def LibraryCall(ptr):
n = ctypes.cast(ptr,ctypes.POINTER(ctypes.c_double))
x = n[0]
y = n[1]
area = dblquad(lambda x, y: x*y, 0, 0.5, lambda x: 0, lambda x: 1-2*x)
return_val = area[0], area[1]
r_val = (ctypes.c_double * len(return_val))(*return_val)
rv = ctypes.cast(r_val,ctypes.POINTER(ctypes.c_double))
#All three of these return the same data:
return (r_val)
#return (rv)
#return (return_val)
lib_call = LibraryCB(LibraryCall)
lib_call = ctypes.cast(lib_call,ctypes.POINTER(ctypes.c_longlong))
Я также пытался использовать эти объявления, но нет никакой разницы:
LibraryCB = ctypes.WINFUNCTYPE(None, ctypes.POINTER(ctypes.c_double))
LibraryCB = ctypes.PYFUNCTYPE(None,ctypes.POINTER(ctypes.c_double))
Вот часть кода NASM, которая вызывает обратный вызов и получаетуказатель обратно из обратного вызова в переменной [dblquad_Pointer]):
pop rbp
pop rdi
sub rsp,32
call [scipy.integrate_dblquad_Pointer]
add rsp,32
push rdi
push rbp
mov [dblquad_Pointer],rax
; check the values returned
lea rdi,[rel dblquad_Pointer]
mov rbp,qword [rdi] ; Return Pointer
movsd xmm0,qword[rbp]
ret
Я пробовал три отдельных вызова, чтобы вернуть указатель на dll:
return (r_val)
return (rv)
return (return_val)
Все три из нихвернуть тот же неверный результат из DLL обратно в ctypes.
Предложенное решение, когда я опубликовал это последнее, состояло в том, чтобы изменить код DLL для использования параметра ввода / вывода, например, на C, но я не знаю эквивалента в NASM.
Итак, чтобы подвести итог, мой вопрос, если у меня есть обратный вызов от отправляющих и получающих указатели dll NASM, как мне обработать указатель, возвращенный обратно в dll?