gpt4 book ai didi

c - Fortran/Mac OS X 中 ISO_C_binding "c_intptr_t"返回的值不正确

转载 作者:行者123 更新时间:2023-12-02 18:01:09 25 4
gpt4 key购买 nike

我有以下 Fortran 函数 create_pointer,它调用名为 create_pointer 的 C 函数,该函数创建一个指针并返回其地址:

FUNCTION create_pointer() RESULT(c_intptr_t) BIND(C, name = "create_pointer")
USE, INTRINSIC :: iso_c_binding, ONLY: c_intptr_t
END FUNCTION

作为引用,C 函数 create_pointer 如下:

intptr_t create_pointer(void)
{
void *ptr;
intptr_t address;

ptr = malloc(100);
address = (intptr_t) ptr;
printf("FROM C: address %p\n", address)
return address;
}

现在,在 Mac OS X 64 位中编译(使用 GCC 4.9)并执行以下 Fortran 程序时:

PROGRAM

INTEGER(c_intptr_t) :: address

address = create_pointer()

WRITE(*, '(Z8)') "FROM FORTRAN:", address

END PROGRAM

它给出了一个意外的输出,可能与此类似:

FROM C: address 0x7f8870c3ee00
FROM FORTRAN: address 70C3EE00

为什么 C 语言显示的地址与 Fortran 语言显示的地址不同?我假设 ISO_C_binding c_intptr_t 将保留这两种语言之间的正确值。另外,可以注意到,Fortran 从 C 接收到的地址包含在其中(换句话说,初始值 0x7f88 被丢弃)。是因为64位地址计数中只有前48位而ISO_C_绑定(bind)丢弃了最后16位吗?

仅供引用,这次在 Ubuntu 64 位中编译(使用 GCC 4.9)并运行相同的 Fortran 程序时,输出是一致的(即 C 和 Fortran 显示的地址相同)。

最佳答案

您的错误在这里:

FUNCTION create_pointer() RESULT(c_intptr_t) BIND(C, name = "create_pointer")

您应该将变量名称放在函数声明的 result 部分中。然后,您可以使用您在函数体内放置的名称,并且函数终止时它所具有的值将是函数返回的结果值。

在代码中,您输入名称c_intptr_t,它与您刚刚从内部模块导入的名称一致,并且您可以有效地覆盖它。我认为这不是本意。

此外,正如 @francescalus 所说,您没有隐式没有,因此您让默认值 implicit rules Fortran 选择结果变量的类型;它选择默认实数(因为变量名称以字母 C 开头) - 这就是指针大小为 32 位的原因。

c_intptr_tconstant内部模块内部iso_c_binding 旨在用作可互操作整数的类型参数,以获取系统的正确指针大小。

您可以更改结果中变量的名称,例如更改为 ptr,并将函数声明更改为:

function create_pointer() result(ptr) bind(C, name = "create_pointer")
use, intrinsic :: iso_c_binding, only: c_intptr_t
implicit none
integer(c_intptr_t) :: ptr
end function

关于c - Fortran/Mac OS X 中 ISO_C_binding "c_intptr_t"返回的值不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51323704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com