将代码从 32 位更改为 64 位后,将指针从 Microsoft Visual C++ 传递到 Fortran 并返回
Passing pointer from Microsoft Visual C++ to Fortran and back after changing code from 32 bit to 64 bit
在 Fortran 中调用 C 函数(在 Visual Studio 64 位中编译):
SUBROUTINE GET_PNTR
INTEGER*8 NXLOC(41)
REAL*4 WRX25I(41)
NXLOC(1) = IVRLOC( WRX25I(1) )
RETURN
END
C 函数定义为:
long long IVRLOC(var)
void *var;
{
return var;
}
当我停在 return 语句时,var
被定义为
FORTRAN_X64.exe!0x00007ff6de5b8074
.
- 将地址转换为 big endian 得到 32758 -564428684
- 将地址转换为小端字节序得到 -159449088 1954569182
当我退出函数时,只有最后 4 个字节(在本例中为 -564428684)显示为 NXLOC(1) 的值。我不确定这是否正确,但似乎不可能,并且由于下一步使用该地址失败,因此似乎已确认它是不正确的。通过搜索网络,该值似乎应该是小端,但这不是我所看到的。
这是怎么回事?
Fortran 代码中的下一步,当使用地址时,看起来像:
PROGRAM USE_PTR
INTEGER*8 NXLOC(41)
REAL*4 XSLAM(41)
NX = 41
CALL VALOCX(NXLOC(1),XSLAM(1),NX)
RETURN
END
C 函数的样子:
void VALOCX( nsloc, vals, ns)
float *nsloc[], vals[];
int *ns;
{
int i;
for (i=0; i<*ns; i++) {
vals[i] = *nsloc[i];
}
}
此函数中的 nsloc
现在具有值
0x00007ff6de5b3c00 {FORTRAN_X64.exe!CHKSUB} {0xffffffffde5b8074 {???}}
其中只恢复了原始变量地址的最后四个字节。我假设我需要在某个时候从大端转换为小端,但到目前为止我的努力似乎只会增加我的困惑。
为什么“var”在退出 IVRLOC 时不转换为正确的值,以便它在 VALOCX 中转换回正确的值?
如果您没有将 IVRLOC
声明为在 Fortran 端返回 INTEGER*8
(或者 INTEGER(c_intptr_t)
)的函数,则它的类型为默认整数,可能是 4-字节整数。这可以解释由于类型不匹配,原始 8 字节值的一半被设置为零。
在 Fortran 中调用 C 函数(在 Visual Studio 64 位中编译):
SUBROUTINE GET_PNTR
INTEGER*8 NXLOC(41)
REAL*4 WRX25I(41)
NXLOC(1) = IVRLOC( WRX25I(1) )
RETURN
END
C 函数定义为:
long long IVRLOC(var)
void *var;
{
return var;
}
当我停在 return 语句时,var
被定义为
FORTRAN_X64.exe!0x00007ff6de5b8074
.
- 将地址转换为 big endian 得到 32758 -564428684
- 将地址转换为小端字节序得到 -159449088 1954569182
当我退出函数时,只有最后 4 个字节(在本例中为 -564428684)显示为 NXLOC(1) 的值。我不确定这是否正确,但似乎不可能,并且由于下一步使用该地址失败,因此似乎已确认它是不正确的。通过搜索网络,该值似乎应该是小端,但这不是我所看到的。
这是怎么回事?
Fortran 代码中的下一步,当使用地址时,看起来像:
PROGRAM USE_PTR
INTEGER*8 NXLOC(41)
REAL*4 XSLAM(41)
NX = 41
CALL VALOCX(NXLOC(1),XSLAM(1),NX)
RETURN
END
C 函数的样子:
void VALOCX( nsloc, vals, ns)
float *nsloc[], vals[];
int *ns;
{
int i;
for (i=0; i<*ns; i++) {
vals[i] = *nsloc[i];
}
}
此函数中的 nsloc
现在具有值
0x00007ff6de5b3c00 {FORTRAN_X64.exe!CHKSUB} {0xffffffffde5b8074 {???}}
其中只恢复了原始变量地址的最后四个字节。我假设我需要在某个时候从大端转换为小端,但到目前为止我的努力似乎只会增加我的困惑。
为什么“var”在退出 IVRLOC 时不转换为正确的值,以便它在 VALOCX 中转换回正确的值?
如果您没有将 IVRLOC
声明为在 Fortran 端返回 INTEGER*8
(或者 INTEGER(c_intptr_t)
)的函数,则它的类型为默认整数,可能是 4-字节整数。这可以解释由于类型不匹配,原始 8 字节值的一半被设置为零。