从fortran调用c函数(类型为enum)

时间:2018-08-06 15:29:20

标签: c enums fortran typedef fortran-iso-c-binding

最近,我用iso_c_binding从fortran调用了c函数。但是我发现了一些c代码,例如:

typedef enum
{
    STRUMPACK_FLOAT,
    STRUMPACK_DOUBLE,
    STRUMPACK_FLOATCOMPLEX
} STRUMPACK_PRECISION;

typedef enum
{
    STRUMPACK_MT,
    STRUMPACK_MPI_DIST
} STRUMPACK_INTERFACE;

typedef struct
{
    int solver;
    STRUMPACK_PRECISION precision1;
    STRUMPACK_INTERFACE interface1;
}STRUMPACK_SparseSolver;

int STRUMPACK_init(STRUMPACK_SparseSolver * S,
    STRUMPACK_PRECISION precision1, STRUMPACK_INTERFACE interface1, int verbose)
{
    S->precision1 = precision1;
    S->interface1 = interface1;
    switch (interface1)
    {
        case STRUMPACK_MT:
        {
            switch (precision1)
            {
                case STRUMPACK_FLOAT:
                    printf("srtumpack_float %d\n", verbose);
                    break;
                case STRUMPACK_DOUBLE:
                    printf("srtumpack_double %d\n", verbose);
                    break;
                default:
                    printf("ERROR: wrong precision!");
            }
        }
            break;
        default:
            printf("ERROR: wrong interface!");
    }
    return 0;
}

我不知道用Fortran调用此c子函数,因为这种结构:

typedef enum
{
  STRUMPACK_MT,
  STRUMPACK_MPI_DIST
} STRUMPACK_INTERFACE;

我不知道如何解决这个问题。对于这个问题的任何建议和建议,我将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:1)

这不是结构,而是ISO绑定实体enum支持的ENUM(枚举)。

如果您的绑定缺失枚举枚举,则以下是一种解决方法。 C中的枚举或多或少是常量整数,这些值由编译器以通常递增的方式分配。您还可以按如下所示使用赋值来强制每个enum成员的值:

typedef enum
{
  STRUMPACK_FLOAT = 0,
  STRUMPACK_DOUBLE,
  STRUMPACK_FLOATCOMPLEX = 100
} STRUMPACK_PRECISION

在这种情况下,即我们将STRUMPACK_FLOATCOMPLEX的值强加到100。我们对第一个成员进行了相同的设置,无论如何,默认情况下第一个成员的值为0。第二个成员STRUMPACK_DOUBLE将从前一个成员获得1作为递增值。 无论如何,您都可以获得有关enum如何在网上进行谷歌搜索的更好信息。

在您的情况下,解决问题的更简单方法是在定义中转换枚举,并使用int作为类型,如:

#define STRUMPACK_FLOAT         0
#define STRUMPACK_DOUBLE        1
#define STRUMPACK_FLOATCOMPLEX  2
typedef int STRUMPACK_PRECISION;

#define STRUMPACK_MT            0
#define STRUMPACK_MPI_DIST      1
typedef int STRUMPACK_INTERFACE;

typedef struct
{
    int solver;
    STRUMPACK_PRECISION precision1;
    STRUMPACK_INTERFACE interface1;
} STRUMPACK_SparseSolver;

int STRUMPACK_init(STRUMPACK_SparseSolver * S, STRUMPACK_PRECISION precision1,
                                        STRUMPACK_INTERFACE interface1, int verbose)
{
    S->precision1 = precision1;
    S->interface1 = interface1;
    switch (interface1)
    {
        case STRUMPACK_MT:
        {
            switch (precision1)
            {
                case STRUMPACK_FLOAT:
                    printf("srtumpack_float %d\n", verbose);
                    break;
                case STRUMPACK_DOUBLE:
                    printf("srtumpack_double %d\n", verbose);
                    break;
                default:
                    printf("ERROR: wrong precision!");
            }
        }
            break;
        default:
            printf("ERROR: wrong interface!");
    }
    return 0;
}