簡體   English   中英

將字符串從Fortran返回到C ++

[英]Return string from Fortran to C++

我在C ++中有以下函數調用:

int strLength = 20;
char* name;

getName(name, strLength);

printf("name: %s\n", name);

在Fortran:

subroutine getName(name) bind (c, name='GETNAME')
use,intrinsic :: iso_c_binding
implicit none
character, intent(out) :: name

name = 'Martin'
end subroutine getName

當我執行C ++例程時,輸出為: name: M 現在,我想這是因為character, intent(out) :: name聲明了大小為1的name變量,但如果我將聲明更改為: character(len=6), intent(out) :: name我得到此錯誤消息: Error: Character argument 'name' at (1) must be length 1 because procedure 'getname' is BIND(C) 我也嘗試了這個: character(len=6,kind=c_char), intent(out) :: name ,具有相同的錯誤消息。 最后,我嘗試了這個聲明: character(c_char),dimension(6), intent(out) :: name ,它編譯但是產生了這個結果: name: MMMMMM

我的問題歸結為:如何從Fortran返回一個字符串到C ++?

這種基於Fortran函數的方法干凈整潔,在C例程中尚未設置字符串(或為其分配內存)時非常適合。 請注意,您不需要傳入字符串長度參數,也不需要使用假定大小的數組來構建/返回字符串值。 1

使用Fortran可分配字符串常量,以便此函數可以重用於任何字符串。

例如,整數參數也會傳遞到Fortran函數中,以演示如何指示所需的響應應該是什么。

請注意,在此示例中,“intent(out)”用於指示在傳入之前不需要定義整數參數,但可以在返回之前更新它。 因此,您可以修改其值並將其返回給調用程序,以便它可以用作“返回代碼”。

Fortran函數

! f_string.f90
! Called from C routine as:  `myString = get_string(rc)`

function get_string(c_rc) bind(c, name='get_string')
    use, intrinsic :: iso_c_binding
    implicit none
    integer(c_int), intent(out) :: c_rc           ! <- Pass by reference; acts as return code in this example.
    type(c_ptr) :: get_string                     ! <- C_PTR to pass back to C
    character(len=:), allocatable, target, save :: fortstring   ! <- Allocatable/any length is fine

    fortstring = "Append C_NULL_CHAR to any Fortran string constant."//C_NULL_CHAR
    get_string = c_loc(fortstring)                ! <- C_LOC intrinsic gets loc of our string.
    c_rc = 1                                      ! <- Set the return code value.
end function get_string

C計划

// c_string.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *get_string(int *rc);              // <- The Fortran function signature.

int main(){
    int rc;                             // <- No value set.
    char *mynameptr;                    // <- Just a plain ol' char *, no memory allocation needed.

    mynameptr = get_string(&rc);

    printf("mynameptr=%s\n", mynameptr);
    printf("len =%d\n", strlen(mynameptr));
    printf("rc  =%d\n", rc);
    return rc;
}

編譯,調用,輸出:

ifort /c f_string.f90
icl c_string.c /link f_string.obj
c_string.exe
# example output: 
# mynameptr=Append C_NULL_CHAR to any Fortran string constant.
# len =48
# rc  =1

1這也可以在沒有警告的情況下干凈地編譯( OP的解決方案確實發生了這種情況,而沒有我在評論中提出的修改)。

問題在於將等級n的字符數組分配給長度為n的字符標量,這在問題中得到了解決。 如下所示更改Fortran例程解決了這個問題。

由於我在遺留系統中工作,我不得不尋求下面所示的解決方案。 顯然它並不完全相同,但它仍然顯示了一般結構。 如果其他人也應該采用這種解決方案,你應該遵循Matt P評論中的建議。

雖然這是我所采用的解決方案,但我覺得Matt P的答案是問題標題中所述的一般問題的更好解決方案,這就是為什么我接受這個作為答案的原因。

C ++

int strLength = 20;
char* name = new char[strLength];   
getName(name, strLength);    
printf("name: %s\n", name);

Fortran語言

subroutine getName(name) bind (c, name='GETNAME')
use,intrinsic :: iso_c_binding
implicit none
character(c_char),dimension(20), intent(out) :: name
character(20) :: fName

fName = 'Martin'//c_null_char

do j=1,len(fName )
  name(j) = fName (j:j)  
enddo

end subroutine getName

暫無
暫無

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

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