代码之家  ›  专栏  ›  技术社区  ›  RTC222

无法访问传递给NASM 64位DLL的数组指针

  •  2
  • RTC222  · 技术社区  · 7 年前

    我将两个数组的指针从Python程序(使用ctypes)传递到NASM 64位DLL。在Windows调用约定中,指针在rcx和rdx中传递。这两个阵列都是Int64。数组是在Python中创建的,并通过以下方式传递到DLL:

    PassArrayType = ctypes.c_int64 * 10
    PVarrNew = PassArrayType()
    OutputArrayType = ctypes.c_int64 * 1000
    arrNew = OutputArrayType()
    retvar = SimpleTest(ctypes.byref(PVarrNew), ctypes.byref(arrNew))
    

    在DLL中,我可以读取rcx中的数组指针,但无法写入数组。

    例如,从rcx指向的数组中读取值可以:

    push qword [rcx+32]
    pop qword [tempvar]
    

    但将值写入rcx指向的数组不起作用:

    mov rax,1235
    push rax
    pop qword [rcx+32]
    

    当将相同的值写入变量时:

    mov rax,1235
    push rax
    pop qword [tempvar]
    

    我无法读取或写入rdx指向的数组。

    所以我的问题是:

    1. 为什么我可以从rcx指向的数组中读取,但不能写入它?
    2. 为什么我不能读取或写入rdx指向的数组?

    迈克尔,谢谢你的回复。我把minimal误解为只指有争议的代码行。我对堆栈溢出相当陌生,但现在我知道要发布多少代码。这是完整的Python代码和完整的NASM代码。Python是3.6.2。NASM是64位的。

    Python代码:

    OutputArrayType = ctypes.c_int64 * 1000
    arrNew = OutputArrayType()
    
    PassArrayType = ctypes.c_int64 * 10
    PVarrNew = PassArrayType()
    PVarrNew[0] = id(PVarrNew)
    PVarrNew[1] = 2
    PVarrNew[2] = len(PVarrNew)
    
    ThisDll = ctypes.WinDLL(r"C:/Temp2/Std_Math_Formulas.dll")
    SimpleTest = ThisDll.SimpleTest
    SimpleTest.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
    SimpleTest.restype = ctypes.c_int64
    
    retvar = SimpleTest(ctypes.byref(PVarrNew), ctypes.byref(arrNew))
    

    NASM代码:

    ; Header Section
    [BITS 64]
    
    export SimpleTest
    section .data
    tempvar:  dq 0
    
    section .text
    finit
    
    SimpleTest:
    
    push rdi
    push rbp
    
    mov rdi,rcx
    mov rbp,rdx
    
    push qword [rcx+32]
    pop qword [tempvar]
    
    ; this works with rcx, but not rdx
    mov rdi,rcx
    push qword [rdi+32]
    pop qword [tempvar]
    
    ; this works with rcx, but not rdx
    mov rax,1235
    push rax
    pop qword [rcx+32]
    
    mov rax,[tempvar]
    
    pop rbp
    pop rdi
    ret
    

    我将我的DLL组装并链接到:

    nasm -Z myfile.err -f Win64 C:\Temp2\Std_Math_Formulas.asm -l myfile.lst -F cv8 -g -o C:\Temp2\Std_Math_Formulas.obj 
    GoLink Std_Math_Formulas.obj /dll /entry SimpleTest msvcrt.dll 
    
    1 回复  |  直到 7 年前
        1
  •  2
  •   RTC222    7 年前

    迈克尔·佩奇提出的上述解决方案解决了这个问题。正如Michael提议的那样,我从GoLink链接器命令字符串中删除了“/entry SimpleTest”,现在我可以从rcx和rdx指向的数组中读取和写入。正确的命令字符串为:

    GoLink Std_Math_Formulas.obj /dll msvcrt.dll
    

    非常感谢您的解决方案;我非常感谢你的帮助。