In Fortran a C function is called (compiled in Visual Studio 64 bit):
SUBROUTINE GET_PNTR
INTEGER*8 NXLOC(41)
REAL*4 WRX25I(41)
NXLOC(1) = IVRLOC( WRX25I(1) )
RETURN
END
With the C function defined as:
long long IVRLOC(var)
void *var;
{
return var;
}
When I stop at the return statement, var
is defined as
FORTRAN_X64.exe!0x00007ff6de5b8074
.
When I step out of the function only the last 4 bytes (-564428684 in this case) of the big endian are shown for the value of NXLOC(1). I'm not sure if this is right or not, but it seems like it can't be and since the next step to use the address fails that it is incorrect seems confirmed. From searching the web it seems like the value should be little endian, but that is not what I'm seeing.
What is going on?
The next step in the Fortran code, when the address is used, looks like:
PROGRAM USE_PTR
INTEGER*8 NXLOC(41)
REAL*4 XSLAM(41)
NX = 41
CALL VALOCX(NXLOC(1),XSLAM(1),NX)
RETURN
END
Where the C function looks like:
void VALOCX( nsloc, vals, ns)
float *nsloc[], vals[];
int *ns;
{
int i;
for (i=0; i<*ns; i++) {
vals[i] = *nsloc[i];
}
}
nsloc
in this function now has the value
0x00007ff6de5b3c00 {FORTRAN_X64.exe!CHKSUB} {0xffffffffde5b8074 {???}}
where only the last four bytes of the original variable address is recovered. I'm assuming I need to convert from big endian to little endian at some point, but my efforts so far only seem to add to my confusion.
Why doesn't "var" convert to the correct value when exiting IVRLOC so that it converts back to the correct value in VALOCX?
If you are not declaring IVRLOC
as a function returning INTEGER*8
(or maybe INTEGER(c_intptr_t)
) on the Fortran side, it's of type default integer which will likely be a 4-byte integer. Which could explain half of the original 8-byte value being set to zero due to the type mismatch.