簡體   English   中英

在Visual Studio中將可變長度的C字符串轉換為Fortran字符串

[英]Converting a variable length c-string to Fortran string in Visual Studio

我需要將C字符串轉換為Fortran字符串。 在調試示例代碼時,在帶有Intel 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   

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之間的差異,請參考stdcall和cdecl

這個問題尚不清楚,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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM