接受的答案包含两个错误(将错误的字符串长度值传递给
GETCWD
,并留下了
C_NULL_CHAR
)。这个答案纠正了这些错误,并使接口在Fortran中更易用。
基本思想是相同的:使用C调用
getcwd
或
_getcwd
,并使用Fortran的C互操作特性调用C包装器。在Fortran方面,一个包装子程序被用来处理字符串长度,因此不必显式地传递它。
此外,
C_INT
和
C_CHAR
不一定与默认整数和默认字符相同,在Fortran方面需要它们(虽然在实践中我不知道任何
C_CHAR
和默认字符不同的系统)。包装器也会进行转换。从C返回的字符串包含终止的
C_NULL_CHAR
,必须将其删除才能在Fortran方面使用该字符串。
C代码:
#ifdef _WIN32
#include <direct.h>
#define GETCWD _getcwd
#else
#include <unistd.h>
#define GETCWD getcwd
#endif
int getCWDHelper(char *str, int len)
{
return GETCWD(str, len) != str;
}
Fortran代码:
module cwd
use iso_c_binding, only: C_INT, C_CHAR, C_NULL_CHAR
implicit none
private
public :: getCWD
interface
function getCWDHelper(str, len) bind(C, name="getCWDHelper")
use iso_c_binding, only: C_INT, C_CHAR
integer(kind=C_INT) :: getCWDHelper
character(kind=C_CHAR), intent(out) :: str(*)
integer(kind=C_INT), value :: len
end function getCWDHelper
end interface
contains
function getCWD(str)
integer :: getCWD
character(*), intent(out) :: str
integer :: i, length
character(len=len(str), kind=C_CHAR) :: str_copy
getCWD = getCWDHelper(str_copy, len(str_copy, kind=C_INT))
if (getCWD /= 0) then
str = ''
return
end if
length = index(str_copy, C_NULL_CHAR) - 1
do i = 1, length
str(i:i) = char(ichar(str_copy(i:i)))
end do
str(length+1:) = ''
end function getCWD
end module
测试代码:
program test
use cwd, only: getCWD
implicit none
character(len=255) :: path
integer :: error
error = getCWD(path)
print *, error
if (error == 0) print *, path
end program
将返回值分配为可分配的并循环以获得足够的大小留给读者自行练习。最初的回答。
PWD
更改为CD
:call get_environment_variable('CD',currDir)
。但这在Windows上无法工作(我已尝试使用gfortran和ifort)。 你有什么建议吗? - Bayraktaroglu