gpt4 book ai didi

c++ - 当我将一个指针从 Fortran 传递给 C++ 时,第一个元素的值丢失了

转载 作者:太空狗 更新时间:2023-10-29 21:41:19 25 4
gpt4 key购买 nike

我正在从 C++ 调用一个 Fortran 函数,该函数分配一个 vector ,然后它从 C++ 返回一个指向该 vector 的指针。问题是,当我使用此指针在 C++ 中打印值时, vector 第一个元素的值丢失了。我不确定我是否做错了什么。

以下是我的C++代码:

#include <iostream> 
#include <cstdio>

using namespace std;

extern"C" {
void fortfunc_(int *ii, void *ff);
}

main()
{

int ii=5;
double *ff;
int i;

// Calling my Fortran function:
fortfunc_(&ii, &ff);

printf("#C++ address: %p\n", ff);

for (i=0; i<ii; i++)
printf(" ff[%3d] = %f\n",i,ff[i]);

return 0;
}

我的 Fortran 代码:

subroutine fortfunc(ii,ffp)

use, intrinsic :: iso_c_binding
integer(kind=4), intent(in) :: ii
type(C_PTR), intent(out) :: ffp

real(kind=8), dimension(:), allocatable, target :: ff
integer(kind=4) :: err, i

!Allocating memory for ff:
allocate(ff(ii),stat=err)
print *,'allocate returned: ',err

ffp = C_LOC(ff(1))

write(*,'(a,z20)') '#Fortran address:', C_LOC(ff(1))

do i=1,ii
ff(i) = i
end do

print*,"Writing some vectors:"
print*,"ii = ",ii
print*,"ff= ",ff

return
end

如果我运行它,我会得到以下输出:

allocate returned:            0
#Fortran address: 3B5AE0
Writing some vectors:
ii = 5
ff= 1.0000000000000000 2.0000000000000000 3.0000000000000000 4.0000000000000000 5.0000000000000000
#C++ address: 003B5AE0
ff[ 0] = 0.000000
ff[ 1] = 2.000000
ff[ 2] = 3.000000
ff[ 3] = 4.000000
ff[ 4] = 5.000000

如你所见,ff[0] = 0 且必须为 1。

最佳答案

如果您正在引用 ISO_C_BINDING 内部模块,那么您的 Fortran 编译器几乎肯定支持 C 互操作 Fortran 过程和接口(interface)的 BIND(C) 后缀。将后缀 BIND(C, NAME='what_you_want_the_thing_called_in_C") 放在子例程语句上,并避免 Fortran 过程的符号名称周围所有处理器相关的愚蠢行为。这也确保了参数被传入一种 C 互操作方式。

Fortran 子例程中的变量 ff 是一个本地的、未保存的可分配变量。从 Fortran 95 开始,当子程序完成执行时,它会自动释放。该对象的第一个元素的 C 地址在那时变得无效 - 因此在 C 代码中您试图取消引用无效指针(它指向不再分配的内存)。

您需要考虑一些管理 Fortran ff 变量生命周期的方法。一种方法是使它成为 Fortran 指针,并提供一个单独的 Fortran 例程来指示何时可以释放该指针。

关于c++ - 当我将一个指针从 Fortran 传递给 C++ 时,第一个元素的值丢失了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29153501/

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