[英]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.