当只有 C_LOC 地址返回给 C 程序时,Fortran 变量需要 SAVE 属性吗?
SAVE attribute needed for Fortran variables when only the C_LOC address is returned to a C program?
通常,SAVE
属性用于 Fortran 类型声明,以便变量在子程序结束时保留其值,如 SO 问题 here. However, I recently gave an example at 的答案所述如何编写 Fortran 函数 returns 仅 可分配字符串常量的 C 地址到 C 调用程序,具有 C_LOC 内在和其他 ISO_C_BINDING F2003的特点。是否应在 Fortran 可分配字符串常量上使用 SAVE
属性以避免潜在问题?
虽然我没有使用 SAVE
,但该函数按预期工作:C 程序使用 char*
指向 Fortran 函数返回的地址,然后可以将其用作正常(例如,用于打印和 strlen()
)。没有生成 warnings/errors。此外,这似乎与我在编译器文档和相关 SO question 的示例中看到的 C_F_POINTER
的使用方式一致(也就是说,目标值没有 SAVE
属性) .
特别是因为 Fortran 函数是从 C 调用的,所以我不清楚这个过程是否表现出预期的行为,或者它是否 could/should 失败了,或者这是否是特定于供应商的实现细节。 SAVE
(here) 的英特尔 Fortran 17 文档似乎表明默认情况下保存了一个字符串常量(可分配或不可分配?),但我不确定我是否正确阅读,或者how/if 此信息在当前上下文中成立。我是否以便携、正确的方式执行此过程?
虽然我已经链接到代码,但这里是重要的部分:
! f_string.f90: returns the C address to an allocatable string constant:
function get_string() bind(c, name='get_string')
use, intrinsic :: iso_c_binding
implicit none
type(C_PTR) :: get_string
character(len=:), allocatable, target :: fortstring ! <- Include SAVE?
fortstring = "Hello Whosebug" // C_NULL_CHAR ! <- NULL-terminated string constant
get_string = C_LOC(fortstring)
end function get_string
// c_string.c: uses a char* to point at the address returned by 'get_string'
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *get_string(void); // <- Fortran fcn signature
int main(){
char *mycharptr;
mycharptr = get_string();
printf("String from Fortran: %s\n", mycharptr);
printf("len = %d\n", strlen(mycharptr));
return 0;
}
编译为 ifort /c f_string.f90
、icl c_string /link f_string.obj
。
没错。需要保存。
当程序退出时,所有可分配的实体都会被释放,除非它们是 save
。
您可以使用 pointer
而不是 allocatable
并且不会自动释放目标。我发现它比 save
更好,因为可能会多次调用该过程。
你的程序可能 "worked" 因为虽然内存块被释放,但它没有被覆盖。所以 C 程序仍然找到了有意义的数据,但在地址上不允许它访问。但是 OS 内存保护并不总是检查此访问。
通常,SAVE
属性用于 Fortran 类型声明,以便变量在子程序结束时保留其值,如 SO 问题 here. However, I recently gave an example at SAVE
属性以避免潜在问题?
虽然我没有使用 SAVE
,但该函数按预期工作:C 程序使用 char*
指向 Fortran 函数返回的地址,然后可以将其用作正常(例如,用于打印和 strlen()
)。没有生成 warnings/errors。此外,这似乎与我在编译器文档和相关 SO question 的示例中看到的 C_F_POINTER
的使用方式一致(也就是说,目标值没有 SAVE
属性) .
特别是因为 Fortran 函数是从 C 调用的,所以我不清楚这个过程是否表现出预期的行为,或者它是否 could/should 失败了,或者这是否是特定于供应商的实现细节。 SAVE
(here) 的英特尔 Fortran 17 文档似乎表明默认情况下保存了一个字符串常量(可分配或不可分配?),但我不确定我是否正确阅读,或者how/if 此信息在当前上下文中成立。我是否以便携、正确的方式执行此过程?
虽然我已经链接到代码,但这里是重要的部分:
! f_string.f90: returns the C address to an allocatable string constant:
function get_string() bind(c, name='get_string')
use, intrinsic :: iso_c_binding
implicit none
type(C_PTR) :: get_string
character(len=:), allocatable, target :: fortstring ! <- Include SAVE?
fortstring = "Hello Whosebug" // C_NULL_CHAR ! <- NULL-terminated string constant
get_string = C_LOC(fortstring)
end function get_string
// c_string.c: uses a char* to point at the address returned by 'get_string'
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *get_string(void); // <- Fortran fcn signature
int main(){
char *mycharptr;
mycharptr = get_string();
printf("String from Fortran: %s\n", mycharptr);
printf("len = %d\n", strlen(mycharptr));
return 0;
}
编译为 ifort /c f_string.f90
、icl c_string /link f_string.obj
。
没错。需要保存。
当程序退出时,所有可分配的实体都会被释放,除非它们是 save
。
您可以使用 pointer
而不是 allocatable
并且不会自动释放目标。我发现它比 save
更好,因为可能会多次调用该过程。
你的程序可能 "worked" 因为虽然内存块被释放,但它没有被覆盖。所以 C 程序仍然找到了有意义的数据,但在地址上不允许它访问。但是 OS 内存保护并不总是检查此访问。