title: What pointer type to return to NASM from a ctypes callback?
body: <p>I am calling a NASM 64 dll from ctypes; it includes a callback to the SciPy function integrate.dblquad.  The callback receives a pointer to an array of two doubles and returns a pointer to an array of two doubles.  The callback function executes correctly and shows the correct results in Python, but I am having trouble returning the pointer back to NASM.  </p>
  
  <p>I posted this question on May 12 as a ctypes question at <a href="https://stackoverflow.com/questions/50307916/what-is-the-correct-pointer-type-to-return-from-a-ctypes-callback">What is the correct pointer type to return from a ctypes callback?</a>.  I received an answer based on C language with a solution I can't use in NASM.  I hope someone can help with how this could work in NASM rather than C.  </p>
  
  <p>Here is the part of the ctypes code that calls the dll and executes the callback:  </p>
  
  <pre><code>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)
  </code></pre>
  
  <p>Here is the callback code: </p>
  
  <pre><code>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))
  </code></pre>
  
  <p>I have also tried using these declarations, but there is no difference:</p>
  
  <pre><code>LibraryCB = ctypes.WINFUNCTYPE(None, ctypes.POINTER(ctypes.c_double))
  
  LibraryCB = ctypes.PYFUNCTYPE(None,ctypes.POINTER(ctypes.c_double))
  </code></pre>
  
  <p>Here is the part of the NASM code that calls the callback and receives the pointer back from the callback in the variable [dblquad_Pointer]):  </p>
  
  <pre><code>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
  </code></pre>
  
  <p>I have tried three separate calls to return the pointer to the dll:  </p>
  
  <pre><code>    return (r_val)
      return (rv)
      return (return_val)
  </code></pre>
  
  <p>All three of them return the same incorrect result from the dll back to ctypes.  </p>
  
  <p>The proposed solution when I posted this last was to change the DLL code to use an input/output parameter, with an example in C, but I know of no equivalent in NASM.  </p>
  
  <p>So to sum it up, my question is, if I have a callback from a NASM dll sending and receiving pointers, how do I handle the pointer returned back to the dll?  </p>