2012-03-13 25 views
11

Tôi đang viết mã sẽ gọi hàm C từ Fortran sử dụng cơ chế tương tác C của Fortran (được giới thiệu trong Fortran 2003 và được triển khai trong các phiên bản mới hơn của gfortran và ifort).Mảng chuỗi trong cầu Fortran-C sử dụng iso_c_binding

This answer là gần như những gì tôi cần, nhưng tôi không thể khá được đầu của tôi xung quanh những gì tuyên bố giao diện tôi nên sử dụng trong Fortran cho một hàm C trông như thế này:

int use_array(int n, char * array[]){ 
    int i; 
    for(i=0; i<n; i++){ 
     printf("Item %d = %s\n",i,array[i]); 
    } 
    return n; 
} 

Tôi không rõ ràng những gì tuyên bố nên được cho giao diện trên đầu Fortran:

interface 
    function use_array(n, x) bind(C) 
     use iso_c_binding 
     integer (c_int) use_array 
     integer (c_int), value :: n 
     character(c_char) WHAT_SHOULD_GO_HERE? :: x 
    end function use_array 
end interface 

Tôi biết rằng tôi sẽ phải đối phó với vấn đề vô hiệu hóa quá.

+0

Rất cám ơn cho người dùng francescalus cho helpfully chỉnh sửa câu hỏi này để làm cho tôi có vẻ ít lịch sự bằng cách loại bỏ một "cảm ơn" ở phần cuối của nó. Cảm ơn những người dùng tốt như họ đang ở xung quanh để ngăn mọi người đặt câu hỏi không đọc được với lịch sự hàng ngày. – JoeZuntz

Trả lời

8

Cách chúng tôi làm là sử dụng mảng C_PTR để trỏ đến chuỗi. Ví dụ:

CHARACTER(LEN=100), DIMENSION(numStrings), TARGET :: stringArray 
TYPE(C_PTR), DIMENSION(numStrings) :: stringPtrs 

sau đó chúng tôi thiết lập chuỗi của chúng tôi trong stringArray, nhớ để null-chấm dứt chúng như:

DO ns = 1, numStrings 
    stringArray(ns) = "My String"//C_NULL_CHAR 
    stringPtrs(ns) = C_LOC(stringArray(ns)) 
END DO 

và vượt qua stringPtrs đến chức năng C.

Chức năng C có giao diện:

void stringFunc(int *numStrings, char **stringArray) { 
    int i; 
    for(i=0;i<*numStrings;++i) { 
     printf("%s\n",stringArray[i]); 
    } 
} 
+0

Tuyệt vời, cảm ơn rất nhiều vì câu trả lời đặc biệt nhanh chóng và hữu ích! Để hoàn thành, kiểu trong giao diện là "type (c_ptr), dimension (numStrings)" – JoeZuntz

+0

Đúng, trong mã của chúng ta, chúng ta không thực sự cung cấp giao diện cho hàm C, chúng ta coi nó là 'external' vì vậy tôi không có một ví dụ dễ dàng về khối giao diện trên tay. – tpg2114

+1

Đây không phải là tiêu chuẩn Fortran 2003 (xem phần 15.2.1) hoặc 2008 (phần 15.3.2): ** Nếu loại là ký tự, tham số kiểu độ dài có thể tương tác nếu và chỉ khi giá trị của nó là một. **. Và gfortran báo hiệu điều này (sử dụng ký tự * (len = ...) * với C_LOC) dưới dạng lỗi. Ngoài ra còn có một [thảo luận] (http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36759) về vấn đề này trong lỗi của GCC. –

Các vấn đề liên quan