无法访问传递给 NASM 64 位 DLL 的数组指针
Unable to access array pointer passed to NASM 64 bit DLL
我将两个数组的指针从 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 指向的数组。
所以我的问题是:
- 为什么我可以从rcx 指向的数组读取但不能写入它?
- 为什么我无法读取或写入 rdx 指向的数组?
迈克尔,感谢您的回复。我误解了 minimal 仅表示有问题的代码行。我是 Stack Overflow 的新手,但现在我明白了 post 需要多少代码。这是完整的 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
我 assemble 和 link 我的 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
Michael Petch 上面提出的解决方案解决了这个问题。我按照 Michael 的建议从 GoLink 链接器命令字符串中删除了“/entry SimpleTest”,现在我可以从 rcx 和 rdx 指向的数组读取和写入。正确的命令字符串是:
GoLink Std_Math_Formulas.obj /dll msvcrt.dll
非常感谢您的解决方案;我非常感谢你的帮助。
我将两个数组的指针从 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 指向的数组。
所以我的问题是:
- 为什么我可以从rcx 指向的数组读取但不能写入它?
- 为什么我无法读取或写入 rdx 指向的数组?
迈克尔,感谢您的回复。我误解了 minimal 仅表示有问题的代码行。我是 Stack Overflow 的新手,但现在我明白了 post 需要多少代码。这是完整的 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
我 assemble 和 link 我的 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
Michael Petch 上面提出的解决方案解决了这个问题。我按照 Michael 的建议从 GoLink 链接器命令字符串中删除了“/entry SimpleTest”,现在我可以从 rcx 和 rdx 指向的数组读取和写入。正确的命令字符串是:
GoLink Std_Math_Formulas.obj /dll msvcrt.dll
非常感谢您的解决方案;我非常感谢你的帮助。