如何使用Fortran接口调用包含用户定义类型的C函数

问题描述 投票:0回答:2

其实我想从fortran中调用magma。所以我添加了 magma.lib 并创建了一个接口来使用 magma 的 C 函数:

Interface
      Integer function magma_dpotrf(uplo, n, a, lda, info) BIND (C, NAME="magma_dpotrf")
        use iso_c_binding
        Implicit none
        !character (c_char), value :: uplo????
        integer (c_int), value ::n
        real (c_double) ::a(*)
        integer (c_int), value ::lda
        integer (c_int)::info
      end function
   end Interface

但是参数uplo是用户定义的类型 在 C 代码中(magma_uplo_t uplo):

typedef enum {
    MagmaUpper         = 121,
    MagmaLower         = 122,
    MagmaUpperLower    = 123,
    MagmaFull          = 123,  /* lascl, laset */
    MagmaHessenberg    = 124   /* lascl */
} magma_uplo_t;

magma_int_t
magma_dpotrf(
    magma_uplo_t uplo, magma_int_t n,
    double *A, magma_int_t lda,
    magma_int_t *info);

magma_int_t = int,有谁知道如何为其创建接口? 预先感谢

c interface fortran user-defined-types magma
2个回答
2
投票

magma_uplo_t
是一个枚举。 Fortran 2003 中对它们有一些支持,但您可以非常安全地假设它是一个
integer(c_int)
,它可以采用 121 到 124 之间的值。在您的情况下,它是按值传递的。

integer(c_int), value :: uplo

您实际上可以使用 Fortran 2003 枚举来创建常量

 enum, bind( C )
    enumerator :: MagmaUpper         = 121, &
                  MagmaLower         = 122, &
                  MagmaUpperLower    = 123, &
                  MagmaFull          = 123, &
                  MagmaHessenberg    = 124
  end enum

但是变量,然后你也可以尝试

integer(kind=kind(MagmaUpper))
以确保完全安全。这将在 GCC 的
--short-enums
选项中继续存在。


0
投票

以前也挖过,但还不满意。这些解决方案怎么样?

!https://community.intel.com/t5/Intel-Fortran-Compiler/named-enum-bind-c/m-p/1103221

    use iso_c_binding
#if NAMED_ENUM
      enum, bind(c) :: color
        enumerator :: red = 4, blue = 9
        enumerator yellow
      end enum
#else
      enum, bind(c)
        enumerator :: red = 4, blue = 9
        enumerator yellow
      end enum
#endif

来自 http://computer-programming-forum.com/49-fortran/cfa557a9177328c6.htm 不允许对类型 (ENUM2) 变量进行表达式。 这是源代码:

program enums
   type enum1
      integer :: value
   end type enum1
   type enum2
      integer :: value
   end type enum2
   type(enum1), parameter :: v1 = enum1(1)
   type(enum1), parameter :: v2 = enum1(2)
   type(enum2), parameter :: w1 = enum2(1)
   type(enum2), parameter :: w2 = enum2(2)
   type(enum1) :: var1
   type(enum2) :: var2
   var1 = v1
   var2 = w1
   write(*,*) var1, var2
   var1 = w1
   var2 = v1
   write(*,*) var1, var2
   stop
end program
© www.soinside.com 2019 - 2024. All rights reserved.