【问题标题】:Error when running Fortran program (forrtl: severe (157): Program Exception - access violation)运行 Fortran 程序时出错(forrtl:严重 (157):程序异常 - 访问冲突)
【发布时间】:2019-06-21 09:16:09
【问题描述】:

我有一个 C 程序,它有一个名为 get_name 的函数。此函数返回一个字符串(即char *)并用字符串的大小更改参数size(传递给它):

char *get_name(int &size)
{
     *size = strlen(name);   // name is a C global variable declared as a char *
     return name;
}

我创建了以下 Fortran 模块,以便能够调用 C 函数get_name

MODULE X

    USE, INTRINSIC :: iso_c_binding, ONLY: c_intptr_t

    IMPLICIT NONE

    INTERFACE

        TYPE(c_ptr) FUNCTION get_name_(size) BIND(C, name = "get_name")
            USE, INTRINSIC :: iso_c_binding, ONLY: c_int, c_ptr
            INTEGER(c_int), INTENT(OUT) :: size
        END FUNCTION

    END INTERFACE

    CONTAINS

        FUNCTION get_name()
            USE, INTRINSIC :: iso_c_binding, ONLY: c_int, c_char, c_f_pointer, c_ptr, c_associated
            !DEC$ ATTRIBUTES DLLEXPORT :: get_name
            CHARACTER(LEN = :), ALLOCATABLE :: get_name
            INTEGER(c_int) :: size
            TYPE(c_ptr) :: c_string

            c_string = get_name_(size)

            IF (c_associated(c_string)) THEN
                BLOCK
                    CHARACTER(KIND = c_char, LEN = size), POINTER :: f_string
                    CALL c_f_pointer(c_string, f_string)
                    get_name = f_string
                END BLOCK
            ELSE
                get_name = ""
            END IF

        END FUNCTION

END MODULE

我可以在 Windows 中使用 IFORT 2016、Linux 中的 IFORT 2016 和 Linux 中的 gfortran 成功编译此 Fortran 模块。

为了测试,我创建了一个简短的 Fortran 程序:

PROGRAM Test

    USE X

    WRITE(*, *) "Name: ", get_name()

END PROGRAM

我可以在 Windows 中使用 IFORT 2016、Linux 中的 IFORT 2016 和 Linux 中的 gfortran 成功编译这个 Fortran 程序。

现在,当运行该程序时,它在 IFORT 2016 for Linux 中运行良好,gfortran 在 Linux 中运行良好,但在 IFORT 2016 for Windows 中运行良好。它实际上给出了以下错误:

 forrtl: severe (157): Program Exception - access violation 

知道如何解决这个错误吗?

【问题讨论】:

    标签: fortran intel-fortran


    【解决方案1】:

    我假设您的 C 函数是 char *get_name(int *size) 而不是使用 C++ 引用。

    然后,此代码可在 Windows 和 Linux 上使用 Ifort 16 和 gcc-6.3.1 或 Visual Studio 2015。

    请添加您使用的 C 编译器和命令行来编译代码。我用过:

    cl -c testc.c && ifort -c testf.f /extend-source:132 && ifort testm.f testf.obj testc.obj /extend-source:132 && testm.exe

    顺便说一句:如果您在并行代码中使用此函数,我建议您避免使用块构造 - 我在 Ifort 16 中使用此并行 (OpenMP) 代码时体验不佳。

    【讨论】:

    • 这并不能真正回答问题。请在 cmets 部分建议代码对您有效的附加信息或 cmets 请求。顺便说一句,即使使用 C++ 参考,它很可能也能正常工作(尽管不能保证)。
    • 感谢@VladimirF 的建议,但不幸的是我还不允许添加 cmets - 我应该删除我的答案吗?我还认为 C++ 引用应该可以工作,但是函数的主体是错误的,我不知道定义 C++ 引用应该像每个编译器的 C 指针一样的标准。
    • 是的,你是对的,那么身体就错了。您可以将其放入答案并保留它,这是有效的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    相关资源
    最近更新 更多