将代码从 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.

当我退出函数时,只有最后 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 字节值的一半被设置为零。