首页 文章

在Visual Studio中将可变长度的c-string转换为Fortran字符串

提问于
浏览
1

我需要将C字符串转换为Fortran字符串 . 当我调试示例代码时,在使用英特尔Visual Fortran Composer XE 2013的Visual Studio 2012中,我遇到了一些问题:

1)我在调试器中看不到延迟长度可分配字符变量( 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

2 回答

  • 0

    1)从Fortran模块中观察变量:使用modulename :: variablename . 你在运行调试版或发行版吗?如果您正在运行发行版,请在项目属性中启用符号 . 如果您正在运行调试版本,.pdb是否与可执行文件位于同一目录中?如果您正在使用Fortran和C,则会有两个pdb文件 . 所有DLL和exes必须位于同一目录中 . 要自动实现此目的,请更改项目设置 . 代替

    + 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(或者视觉工作室版本为10倍) .

    2)重新锁定 . 每当您添加断点并运行时,pdb文件都将锁定 . 如果程序没有运行,它们不应该锁定,除非你的VS版本已经锁定它 . 是否已应用VS SP?此外,请确保C程序和Fortran程序具有相同的调用约定 . 有stdcall和cdecl . 在Fortran中,这是在项目设置中完成的 . 如果没有传递参数并且传递参数时无关紧要,请确保它们都使用相同的约定 .

    有关stdcall和cdecl之间的差异,请参阅stdcall and cdecl

  • 0

    目前还不清楚C代码如何使用Fortran字符串?

    如果字符串来自C函数:

    const char *getcstr(void)
    {
        return "Hello!";
    }
    

    这是调用C函数的完整Fortran程序,将结果转换为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
    

相关问题