如何在C语言中"调用"fortran例程中分配一个数组

mem*_*mem 4 c fortran memory-management fortran-iso-c-binding

我认为头衔说我需要什么.我知道我们可以使用"asd"函数来执行此操作,但由于某些原因,我需要在Fortran中进行分配(即在子例程"asd_"中).这是C代码:

#include <stdio.h>

void asd(float **c) {
  *c = (float *) malloc (2*sizeof(float));
  **c =123;
  *(*c+1)=1234;
}

void asd_(float **c);

main () {
  float *c;
  asd_(&c);
// asd(&c); would do the job perfectly
  printf("%f %f \n",c[0],c[1]);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是Fortran代码:

  subroutine asd(c)

  implicit none

  real, pointer, allocatable ::c(:)

  print *, associated(c)
  if(.not. associated(c))  allocate(c(2))

  end subroutine 
Run Code Online (Sandbox Code Playgroud)

这随机给出了分段错误.任何帮助,将不胜感激.

M. *_* B. 10

Fortran 2003 ISO C绑定提供了一种可移植的方法.它在许多编译器中实现.这是示例代码.

#include <stdio.h>

void test_mem_alloc ( float ** array );

int main ( void ) {

   float * array;
   test_mem_alloc (&array);

   printf ( "Values are: %f %f\n", array [0], array [1] );

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

subroutine test_mem_alloc ( c_array_ptr ) bind (C, name="test_mem_alloc")

   use, intrinsic :: iso_c_binding
   implicit none

   type (c_ptr), intent (out) :: c_array_ptr
   real (c_float), allocatable, dimension (:), target, save :: FortArray

   allocate (FortArray (1:2) )
   FortArray = [ 2.5_c_float, 4.4_c_float ]

   c_array_ptr = c_loc (FortArray)

end subroutine test_mem_alloc
Run Code Online (Sandbox Code Playgroud)

  • 不错的解决方案,但是,我发现“save”的技巧有点黑客:它不是线程安全的,而且也不能再次释放。[在我的帖子中](http://stackoverflow.com/a/38147004/1859258)您找到了一种解决方案,该解决方案基于此解决方案,但修复了这些问题。 (4认同)

mem*_*mem 1

如果您想使用 Fortran 内在类型,这里还有另一种解决方案。这是我的情况,因为我需要使用预先指定的数据类型从外部库调用例程。这基本上是通过包装 Fortran 子例程完成的。这是 C 代码:

void mywrap_(void **);
void myprint_(void *);

main () {
  void *d;
  mywrap_(&d);
  myprint_(d);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是包装器:

  subroutine mywrap(b)
  implicit none
  include "h.h"     
  type(st), target, save :: a
  integer, pointer :: b
  interface 
     subroutine alloc(a)
        include "h.h"
        type(st) a
     end subroutine alloc
  end interface

  call alloc(a)
  b => a%i
  end
Run Code Online (Sandbox Code Playgroud)

以及 Fortran 代码:

  subroutine alloc(a)
  implicit none 
  include "h.h"
  type(st) a

  a%i = 2
  a%r = 1.5
  if (allocated(a%s)) deallocate(a%s)
  allocate(a%s(2))
  a%s(1) = 1.23
  a%s(2) = 1234
  end
  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  subroutine myprint(a)
  implicit none
  include "h.h"     
  type(st) a

  print *,"INT: ", a%i
  print *,"REAL: ", a%r
  print *,"ALLOC: ", a%s
  end
Run Code Online (Sandbox Code Playgroud)

以及头文件“hh”:

  type st
     sequence
     integer i
     real r
     real, allocatable :: s(:)
  end type
Run Code Online (Sandbox Code Playgroud)

注意,这样所有的对象在 C 中都是不透明的。