I am passing pointers two arrays from a Python program (using ctypes) to a NASM 64-bit DLL. In the Windows calling convention, the pointers are passed in rcx and rdx. The two arrays are both Int64. The arrays are created in Python and passed to the DLL this way:
PassArrayType = ctypes.c_int64 * 10
PVarrNew = PassArrayType()
OutputArrayType = ctypes.c_int64 * 1000
arrNew = OutputArrayType()
retvar = SimpleTest(ctypes.byref(PVarrNew), ctypes.byref(arrNew))
In the DLL, I can read from the array pointer in rcx but I can't write to the array.
For example, reading a value from the array pointed to by rcx works:
push qword [rcx+32]
pop qword [tempvar]
But writing a value to the array pointed to by rcx does not work:
mov rax,1235
push rax
pop qword [rcx+32]
While writing the same value to a variable works:
mov rax,1235
push rax
pop qword [tempvar]
I cannot read from OR write to the array pointed to by rdx.
So my questions are:
- Why can I read from the array pointed to by rcx but not write to it?
- Why can't I read or write to the array pointed to by rdx?
Michael, thanks for your reply. I misunderstood minimal to mean only the code lines at issue. I'm fairly new to Stack Overflow, but now I understand how much code to post. Here's the full Python code and the full NASM code. Python is 3.6.2. NASM is 64-bit.
Python code:
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 code:
; 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
I assemble and link my DLL with:
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
/entry SimpleTest
so there is no DLL entry point. since you aren't using the C runtime (yet) you don't need themsvcrt.dll
either. Try it with justGoLink Std_Math_Formulas.obj /dll
– Michael Petchimport ctypes
into the python code you showed it works if the/entry
is left off.It also work if I change RCX to RDX. In that casearrNew[4]
has the value 1235 in it after it returns (the return value will be 0 but that's because the array had 0s in it to begin with) – Michael Petch