在Visual Studio中将变长c字符串转换为Fortran字符串
我需要将C字符串转换为Fortran字符串。在使用英特尔Visual Fortran Composer XE 2013在Visual Studio 2012中调试示例代码时,我遇到了几个问题: 1) 我在调试器中看不到延迟长度可分配字符变量(在Visual Studio中将变长c字符串转换为Fortran字符串,c,arrays,string,visual-studio,fortran,C,Arrays,String,Visual Studio,Fortran,我需要将C字符串转换为Fortran字符串。在使用英特尔Visual Fortran Composer XE 2013在Visual Studio 2012中调试示例代码时,我遇到了几个问题: 1) 我在调试器中看不到延迟长度可分配字符变量(str)的值 2) 在代码中放置断点时,分配此变量类型会导致fCode.pdb文件锁定。释放文件的唯一方法是关闭句柄(通过Process Explorer)或关闭IDE 我在代码中遗漏了什么吗?释放内存?有没有更干净的方法来进行转换 C代码 int main
str
)的值
2) 在代码中放置断点时,分配此变量类型会导致fCode.pdb文件锁定。释放文件的唯一方法是关闭句柄(通过Process Explorer)或关闭IDE
我在代码中遗漏了什么吗?释放内存?有没有更干净的方法来进行转换
C代码
int main ( void ) {
char* cstr = "BP1000";
c_to_f(cstr);
return 0;
}
Fortran代码
module mytest
contains
subroutine c_to_f(cstr) BIND(C, name="c_to_f")
use, intrinsic :: iso_c_binding
!DEC$ ATTRIBUTES DLLEXPORT :: c_to_f
character(kind=C_CHAR, len=1), intent(IN) :: cstr(*)
character(:), allocatable :: str
str = c_to_f_string(cstr)
end subroutine c_to_f
function c_to_f_string(s) result(str)
use, intrinsic :: iso_c_binding
character(kind=C_CHAR, len=1), intent(IN) :: s(*)
character(:), allocatable :: str
integer i, nchars
i = 1
do
if (s(i) == c_null_char) exit
i = i + 1
end do
nchars = i - 1 ! Exclude null character from Fortran string
allocate(character(len=nchars) :: str)
str = transfer(s(1:nchars), str)
end function c_to_f_string
end module mytest
1) 查看Fortran模块中的变量:使用modulename::variablename。您正在运行调试版本还是发布版本?如果正在运行发布版本,请打开项目属性中的符号。如果您正在运行调试版本,.pdb是否与可执行文件位于同一目录中?如果您正在使用Fortran和C语言,那么将有两个pdb文件。所有DLL和EXE必须位于同一目录中。要自动实现这一点,请更改项目设置。而不是
+ solution
+-- C program
+-- debug (both $IntDir and $OutDir point here)
+-- Fortran lib
+-- debug
换成
+ solution
+-- debug (change the project output $OutDir to this place)
+-- C program
+-- debug ($IntDir remains here)
+-- Fortran lib
+-- debug ($IntDir remains here)
还要将.pdb位置更改为$(OutDir)$(TargetName).pdb。默认值为$(IntDir)vc100.pdb(或visual studio版本的10倍)
2) 重新锁定。无论何时添加断点并运行,pdb文件都将锁定。如果程序未运行,则它们不应锁定,除非您的VS版本已将其锁定。是否已应用VS SP?另外,确保C程序和Fortran程序具有相同的调用约定。有stdcall和cdecl。在Fortran中,这是在项目设置中完成的。如果没有传递任何参数,这无关紧要,但在传递参数时,请确保两者使用相同的约定
有关stdcall和cdecl之间的差异,请参阅查看Fortran模块中的变量:使用modulename::variablename。您正在运行调试版本还是发布版本?如果正在运行发布版本,请打开项目属性中的符号。如果您正在运行调试版本,.pdb是否与可执行文件位于同一目录中?如果您正在使用Fortran和C语言,那么将有两个pdb文件。所有DLL和EXE必须位于同一目录中。要自动实现这一点,请更改项目设置。而不是
+ solution
+-- C program
+-- debug (both $IntDir and $OutDir point here)
+-- Fortran lib
+-- debug
换成
+ solution
+-- debug (change the project output $OutDir to this place)
+-- C program
+-- debug ($IntDir remains here)
+-- Fortran lib
+-- debug ($IntDir remains here)
还要将.pdb位置更改为$(OutDir)$(TargetName).pdb。默认值为$(IntDir)vc100.pdb(或visual studio版本的10倍)
2) 重新锁定。无论何时添加断点并运行,pdb文件都将锁定。如果程序未运行,则它们不应锁定,除非您的VS版本已将其锁定。是否已应用VS SP?另外,确保C程序和Fortran程序具有相同的调用约定。有stdcall和cdecl。在Fortran中,这是在项目设置中完成的。如果没有传递任何参数,这无关紧要,但在传递参数时,请确保两者使用相同的约定
有关stdcall和cdecl之间的差异,请参阅问题中不清楚C代码如何使用Fortran字符串 如果字符串来自C函数:
const char *getcstr(void)
{
return "Hello!";
}
下面是完整的Fortran程序,它调用C函数,将结果转换为Fortran字符串,然后打印:
implicit none
interface
function getcstr() bind(c, name="getcstr")
use, intrinsic :: iso_c_binding
type(c_ptr) getcstr
end
end interface
print *, cstr2f(getcstr())
contains
function cstr2f(s)
use, intrinsic :: iso_c_binding
interface
pure function strlen(s) bind(c, name="strlen")
use, intrinsic :: iso_c_binding
type(c_ptr), intent(in) :: s
integer(c_size_t) strlen
end
end interface
type(c_ptr) s
character(kind=c_char, len=strlen(s)), pointer :: cstr2f
call c_f_pointer(s, cstr2f)
end
end
C代码如何使用Fortran字符串的问题还不清楚 如果字符串来自C函数:
const char *getcstr(void)
{
return "Hello!";
}
下面是完整的Fortran程序,它调用C函数,将结果转换为Fortran字符串,然后打印:
implicit none
interface
function getcstr() bind(c, name="getcstr")
use, intrinsic :: iso_c_binding
type(c_ptr) getcstr
end
end interface
print *, cstr2f(getcstr())
contains
function cstr2f(s)
use, intrinsic :: iso_c_binding
interface
pure function strlen(s) bind(c, name="strlen")
use, intrinsic :: iso_c_binding
type(c_ptr), intent(in) :: s
integer(c_size_t) strlen
end
end interface
type(c_ptr) s
character(kind=c_char, len=strlen(s)), pointer :: cstr2f
call c_f_pointer(s, cstr2f)
end
end
祝你好运我会关注这个问题的答案。祝你好运。“我将关注这个问题的答案。”弗朗西斯卡勒斯感谢您的评论,修改了我的答案。我不知道这与问题的第1点和第2点有什么关系。你是说OP所呈现的代码是错误的吗?以哪种方式?他实际上是在问代码中是否遗漏了什么。是吗?Fortran字符串在Fortran中很有用。OP调用C的转换并放弃结果。@francescalus感谢您的评论,修改了我的答案。我不知道这与问题的第1点和第2点有什么关系。你是说OP所呈现的代码是错误的吗?以哪种方式?他实际上是在问代码中是否遗漏了什么。是吗?Fortran字符串在Fortran中很有用。OP从C调用转换并丢弃结果。