Creating a callback function using RtlMoveMemory from kernel32

154 views
Skip to first unread message

Nico

unread,
Dec 28, 2020, 7:27:06 AM12/28/20
to python-cffi
Hey there,

I'm trying to translate calling a function from a fortran DLL from VisualBasic to Python. I can't seem to figure out what causes the issues, but I'm wondering if I also need to do some memory copying like they did in the original VB Version.

Here You can find the documentation of the function I'm calling: https://www.nag.com/numeric/nl/nagdoc_26.1/nagdoc_fl26.1/html/d03/d03ppf.html

Thanks for the help!
Kind regards
Nico

_____________________________________________________________________________
VB CopyMemory:
#If Win32 Then
   Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
   ByRef hpvDest As Any, ByVal hpvSource As Any, ByVal cbCopy As Long)
#Else
   Declare Sub CopyMemory Lib "KERNEL" Alias "hmemcpy" ( _
   ByRef hpvDest As Any, ByVal hpvSource As Any, ByVal cbCopy As Long)
#End If

_____________________________________________________________________________
VB Version:
Private Sub PDEDEF(NPDE As Long, T As Double, x As Double, ByVal ptr_U As Long, ByVal ptr_UX As Long, _
           NCODE As Long, ByVal ptr_V As Long, ByVal ptr_VDOT As Long, _
           ByVal ptr_P As Long, ByVal ptr_Q As Long, ByVal ptr_R As Long, IRES As Long)
  '--- Local Variables:
  Dim i As Integer
  Dim U(1) As Double, UX(1) As Double, P(1, 1) As Double, Q(1) As Double, R(1) As Double
  Dim dblOmega(1) As Double, dblPhi(1) As Double, dblvFH As Double
  Dim dblD As Double, dblDV As Double, dblDP As Double
  Dim dblAD As Double, dblBD As Double, dblCD As Double, dblEa(1) As Double
 
  '--- Save value U und UX in local variables:
  Call CopyMemory(U(1), ptr_U, 8)
  Call CopyMemory(UX(1), ptr_UX, 8)
 
  '--- Some uninteresting calculations happening
  dblOmega(1) = U(1) / (1 + U(1))  
  dblPhi(1) = dblVol(1) * U(1) / (dblVol(1) * U(1) + dblVol(3))
  dblEa(1) = (dblEA_A(1) + dblEA_B(1) * U(1)) / (1 + dblEA_C(1) * U(1))
  dblD = Exp(-(dblDA(1) + dblDB(1) * U(1)) / (1 + dblDC(1) * U(1))) * Exp(-dblEa(1) / 8.314 * (1 / dblTemperatur - 1 / dblTRef(1)))
  dblDV = dblD
  dblDP = (1 - dblPhi(1)) ^ (1 + dblUmrechnung) * dblDV
 
  '--- Defining variables for the PDE:
  P(1, 1) = dblEndfilmdicke ^ 2
  R(1) = dblDP * UX(1)
  Q(1) = 0
 
  '--- Pass local variables to Fortran:
  Call CopyMemory(ByVal (ptr_P), VarPtr(P(1, 1)), 8)
  Call CopyMemory(ByVal (ptr_R), VarPtr(R(1)), 8)
  Call CopyMemory(ByVal (ptr_Q), VarPtr(Q(1)), 8)
 
End Sub

_____________________________________________________________________________
Python Version:
@ffi.callback("void (int*, double*, double*, double[], double[], int*, double[], double[], double[], double[], double[], int*)")
def PDEDEF(NPDE, T, x_loc, U, UX, NCODE, V, VDot, P, Q, R, IRES): # 5
    # --- Some uninteresting calculations happening
    Omega = np.zeros(1, dtype = decTN, order = 'F')
    Phi = np.zeros(1, dtype = decTN, order = 'F')
   
    D = 0.
    DV  = 0.
    DP = 0.
  
    Omega[0] = U[0] / (1 + U[0])
    Phi[0] = Vol[0] * U[0] / (Vol[0] * U[0] + Vol[2])

    if x_loc > x_abbr:
        D = np.exp(-(DiffkoeffA + DiffkoeffB * U[0]) / (1 + DiffkoeffC * U[0]))
    else:
        D = DKGrenz

    DV = D
    DP = (1 - Phi[0]) ** (1 + Umrechnung) * DV
 
    # ---  Defining variables for the PDE:
    P[0][0] = Endfilmdicke ** 2
    R[0] = DP * UX[0]
    Q[0] = 0

Nico

unread,
Dec 28, 2020, 9:05:19 AM12/28/20
to python-cffi
I found out, that an equivalent function to RtlMoveMemory exists within cffi (memmove). But I don't understand when it is necessary to use this function.

Armin Rigo

unread,
Dec 28, 2020, 10:42:36 AM12/28/20
to pytho...@googlegroups.com
Hi Nico,

On Mon, 28 Dec 2020 at 13:27, Nico <Nico....@web.de> wrote:
> I'm trying to translate calling a function from a fortran DLL from VisualBasic to Python. I can't seem to figure out what causes the issues, but I'm wondering if I also need to do some memory copying like they did in the original VB Version.

OK, what is the isuse? What error do you get? Is there a traceback?

> P[0][0] = Endfilmdicke ** 2

This line looks wrong, given that P is a `double[]`. You can't use
two indices on something that is not an array-of-array. You should
get a clear traceback, though, if that is the problem.

The original VB version only uses CopyMemory with the last argument
"8". I think these CopyMemory lines are exactly equivalent to the
ones that do `XYZ[0] = ...` in Python.


Armin

Nico

unread,
Dec 28, 2020, 11:21:40 AM12/28/20
to python-cffi
Hi Armin,

the problem is that I don't know what happens because the kernel just dies. I tried to print something out from inside the callback function to get some information whats going on, but that does not work in that case.

> P[0][0] = Endfilmdicke ** 2

Oh yes, in this example I did a mistake. In the full code I don't distinguish between arrays or arrays of arrays and just say it is a double*. So in this case this is supposed to be an array of an array and the string in the decorator is wrong.

> The original VB version only uses CopyMemory with the last argument
> "8". I think these CopyMemory lines are exactly equivalent to the
> ones that do `XYZ[0] = ...` in Python.

If it is the same, then this might not be the reason my code is failing, so I need to troubleshoot some more why this is not working.

Thank you for the quick response!

Nico
Reply all
Reply to author
Forward
0 new messages