如何返回指针数组?

2024-06-01 01:19:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我从ctypes调用NASM dll。在我的NASM dll代码中,我使用malloc创建了三个数组。它们的指针被指定给final1\u ptr、final2 \u ptr和final3 \u ptr。如果我单独返回任何一个指针,就会得到正确的结果。在

但是我想返回一个包含所有三个指针的数组。为此,我还在.data部分初始化了一个数组:Return_Pointer_array:dq 0,0,0。在

最后,我按如下方式分配指针:

mov rdi,Return_Pointer_Array
mov rax,qword[final1_ptr]
mov qword [rdi],rax
mov rax,qword[final2_ptr]
mov qword [rdi+8],rax
mov rax,qword[final3_ptr]
mov qword [rdi+16],rax
mov rax,rdi
ret

然而,ctypes得到的是一个由三个非常小的小数组成的数组,而不是有效的指针地址。在

实际的程序列表很长,所以我希望上面的代码足以理解这个问题。在

非常感谢你的帮助。在

编辑:如果我返回返回返回的“指针”数组而不指定任何值,则返回双精度(浮点)值。数组被初始化为整数,所以我不明白为什么当它初始化为dq 0,0,0时它默认为浮点。在

编辑2: 根据请求,下面是Python代码:

^{pr2}$

以下是整个NASM列表(有时最小值和完整性会相互矛盾)

; Header Section
[BITS 64]

[default rel]

export Main_Entry_fn

extern malloc, realloc, free

section .data align=16
out_array_pointer: dq 0
call_var_length: dq 0
c_square: dq 0
final1_ptr: dq 0
final1_ctr: dq 0
final2_ptr: dq 0
final2_ctr: dq 0
final3_ptr: dq 0
final3_ctr: dq 0
float_temp_var: dq 0.0
temp_math_var: dq 0
Bool_0: dq 0.0
Bool_1: dq 1.0
data_master_ptr: dq 0
initial_dynamic_length: dq 0
X_ptr: dq 0
X_ctr: dq 0
X: dq 0
n: dq 0
i: dq 0
a: dq 0.0
range_loop_start_a: dq 0
range_loop_end_a: dq 0
b: dq 0.0
range_loop_start_b: dq 0
range_loop_end_b: dq 0
c: dq 0
X_length: dq 0
Input_Length_Array: dq 0,
Return_Pointer_Array: dq 0, 0, 0

section .text

PyGram_Test_01_fn:
xor rcx,rcx
mov [X_ctr],rcx
label_401:
lea rdi,[rel X_ptr]
mov rbp,qword [rdi]
mov rcx,[X_ctr]
cmp rcx,[X_length]
jge exit_label_for_PyGram_Test_01_fn
movsd xmm0,[rbp+rcx]
movsd [n],xmm0
add rcx,8
mov [X_ctr],rcx
movsd xmm0,qword[n]
cvttsd2si rax,xmm0
mov [n],rax
mov rax,[n]
mov rdx,1
add rax,rdx
mov [range_loop_end_a],rax
mov rax,1
sub rax,1
mov [range_loop_start_a],rax
mov [a],rax
label_801:
mov rcx,[a]
inc rcx
cmp rcx,[range_loop_end_a]
jge label_401
mov [a],rcx
mov rax,[a]
sub rax,1
mov [range_loop_start_b],rax
mov [b],rax
mov rax,[n]
mov [range_loop_end_b],rax
label_1201:
mov rcx,[b]
inc rcx
cmp rcx,[range_loop_end_b]
jge label_801
mov [b],rcx
mov rax,[a]
mov r8,[a]
xor rcx,rcx
add rcx,1
Exponent_Label_0:
mul r8
inc rcx
mov rdx,2
cmp rcx,rdx
jl Exponent_Label_0
mov[temp_math_var],rax
mov rax,[b]
mov r8,[b]
xor rcx,rcx
add rcx,1
Exponent_Label_1:
mul r8
inc rcx
mov rdx,2
cmp rcx,rdx
jl Exponent_Label_1
mov rdx,rax
mov rax,[temp_math_var]
add rax,rdx
mov [c_square],rax
mov rax,[c_square]
mov rax,[c_square]
cvtsi2sd xmm1,rax
sqrtsd xmm0,xmm1
cvttsd2si rax,xmm0
mov [c],rax
label_1601:
mov rax,[c]
mov rax,[c]
mov r8,[c]
xor rcx,rcx
add rcx,1
Exponent_Label_2:
mul r8
inc rcx
mov rdx,2
cmp rcx,rdx
jl Exponent_Label_2
mov [temp_math_var],rax
mov rax,[c_square]
mov rdx,[temp_math_var]
sub rax,rdx
mov rdx,0
cmp rax,rdx
jne label_1201
mov rdi,[final1_ptr]
mov rcx,[final1_ctr]
mov rax,[a]
cvtsi2sd xmm0,rax
movsd [rdi + rcx],xmm0
add rcx,8
mov [final1_ctr],rcx
mov rdi,[final2_ptr]
mov rcx,[final2_ctr]
mov rax,[b]
cvtsi2sd xmm0,rax
movsd [rdi + rcx],xmm0
add rcx,8
mov [final2_ctr],rcx
mov rdi,[final3_ptr]
mov rcx,[final3_ctr]
mov rax,[c]
cvtsi2sd xmm0,rax
movsd [rdi + rcx],xmm0
add rcx,8
mov [final3_ctr],rcx
jmp label_1201
label_900:
exit_label_for_PyGram_Test_01_fn:
mov rdi,Return_Pointer_Array
mov rax,qword[final1_ptr]
mov qword [rdi],rax
mov rax,qword[final2_ptr]
mov qword [rdi+8],rax
mov rax,qword[final3_ptr]
mov qword [rdi+16],rax
mov rax,rdi
ret

; __________
; Main Entry

Main_Entry_fn:
push rdi
push rbp
mov [X_ptr],rcx
mov [data_master_ptr],rdx
; Now assign lengths
lea rdi,[data_master_ptr]
mov rbp,[rdi]
xor rcx,rcx
movsd xmm0,qword[rbp+rcx]
cvttsd2si rax,xmm0
mov [X_length],rax
add rcx,8
; __________
; malloc for dynamic arrays
lea rdi,[data_master_ptr]
mov rbp,[rdi]
movsd xmm0,qword[rbp]
cvttsd2si rax,xmm0
mov [initial_dynamic_length],rax
mov rax,3529984
mov [initial_dynamic_length],rax
mov rcx,qword[initial_dynamic_length] ; Initial size
xor rax,rax
sub rsp,40
call malloc
mov qword [final1_ptr],rax
add rsp,40
mov rcx,qword[initial_dynamic_length] ; Initial size
xor rax,rax
sub rsp,40
call malloc
mov qword [final2_ptr],rax
add rsp,40
mov rcx,qword[initial_dynamic_length] ; Initial size
xor rax,rax
sub rsp,40
call malloc
mov qword [final3_ptr],rax
add rsp,40
; __________
call PyGram_Test_01_fn
exit_label_for_Main_Entry_fn:
pop rbp
pop rdi
ret

def PyGram_测试_01(X):

final1, final2, final3 = [],[],[]

下面是汇编程序的Python源代码:

for i, n in enumerate(X):
    n = int(n)
    for a in range(1,n+1):
        for b in range(a,n):
            c_square = a**2 + b**2
            c = int(sqrt(c_square))

            if ((c_square - c**2) == 0):
                final1.append(a)
                final2.append(b)
                final3.append(c)

Tags: addrangelabelraxmovdqptrctr
1条回答
网友
1楼 · 发布于 2024-06-01 01:19:19

我把这个贴出来作为一个答案,因为其他人可能需要这个信息。在迈克尔·佩奇(上图)的帮助下,我解决了这个问题。在

要将指针数组从dll返回到ctypes,请执行以下操作:

  1. 在dll中声明一个数组(对于NASM,它在.data部分声明,例如Return_Pointer_array:dq 0,0,0)。

  2. 退出时,将指针分配给数组(对于汇编程序;在C中,使用C赋值):

    mov rdi,Return_Pointer_Array
    mov rax,qword[final1_ptr]
    mov [rdi],rax
    mov rax,qword[final2_ptr]
    mov [rdi+8],rax
    mov rax,qword[final3_ptr]
    mov [rdi+16],rax
    mov rax,rdi
    
  3. 将返回类型设置为调用名.restype= ctypes.POINTER(ctypes.c_int64)。

  4. 转换每个返回的指针并将数据转换为Python数组(在本例中,我预先知道每个数组中有多少个元素;对于动态数组,长度可以作为返回数组的一个元素返回):

    ret_ptr = CallName(CA_X,length_array_out)
    a = ret_ptr[:3]
    n1 = ctypes.cast(a[0], ctypes.POINTER(ctypes.c_double))
    x1 = n1[:50000]
    n2 = ctypes.cast(a[1], ctypes.POINTER(ctypes.c_double))
    x2 = n2[:50000]
    n3 = ctypes.cast(a[2], ctypes.POINTER(ctypes.c_double))
    x3 = n3[:50000]
    

或者,将返回类型设置为调用名.restype= ctypes.POINTER(ctypes.POINTER(ctypes.c\u double)),如Michael Petch上面所述,并提取如下值:

^{3}$

相关问题 更多 >