2012-05-07 56 views
2

我試圖從C++訪問Fortran公共塊結構中的數組。
我有一個與C++和Fortran混合的示例代碼。C++和Fortran:從C++訪問Fortran公共塊中的數組時出錯Error

Fortran語言:

integer a(5),b 
common /sample/ a,b 
a(1) = 1 
a(2) = 5 
a(3) = 10 
a(4) = 15 
a(5) = 20 
b = 25 

然後在C++:

extern "C"{ 
    extern struct{ 
     int *a,b; 
}sample_; 

從C++,如果我嘗試打印值sample_.b

printf("sample b:%d\n",sample_.b); 

我得到的值( 2):sample b:5

如果我嘗試打印任何其他數組a值我只是得到一個segementation故障...

printf("sample_.a[1]=%d\n",(int)sample_.a[1]); 
printf("sample_.a[0]=%d\n",(int)sample_.a[0]); 

我在做什麼錯?¿任何想法¿?
我想,也許我必須將數組「a」的長度也傳遞給C++,但如果是這樣,我也不知道該怎麼做。

+1

你是不是該數組傳遞給C++代碼。您直接訪問公共塊作爲外部結構。請相應地糾正你的問題。我已經改正了標題。 –

回答

2

我的Fortran生鏽了一點(好的,確實有點),但讓我給它一個旋風。

a可能收到了VALUE而不是指向它的指針。那會將它設置爲1,這不是一個好的指針值。

b收到數據塊中的第二個值。你的C++結構並沒有給編譯器提供什麼數據的真實格式,所以它會按照結構中給出的順序無意識地將項目分配給結構。我會得到一個指向數據塊的指針並手工分解它。

a指定給數據塊的地址(作爲long int指針,看起來像;您的里程可能會有所不同)和b = a[5]。希望有所幫助。

+0

OOPS;可能應該是一個int指針(對不起)。如果分配正確,則[1]應該爲5. – JoeBuddha

+0

關閉時,他沒有收到任何「按值」,而是在「COMMON」塊中,數據按順序排列並且是連續的。基本上,COMMON塊中數組的C/C++結構等價於一個平面數組。 – user7116

+0

是的,如果它是「按價值」,它會有所不同。他得到的是數據塊的地址。把它與整數數組分開仍然是我的工作;然而,我懶得擺弄映射。另外,我最後的Fortran程序是在70年代寫成的。 ;) – JoeBuddha

3

我看來像你的FORTRAN數據實際佈局爲

struct { 
    int a[5]; 
    int b; 
} 

,你是一臺機器,其中sizeof(int) == sizeof(int*)上。

+0

+1,「COMMON」塊的成員通常(不會混淆編譯器選項)在內存中按順序排列。因此,當給定'COMMON'塊'SAMPLE'的起始地址時,數組'A'將與'B'連續。 – user7116

+1

應該注意數據的對齊。默認情況下,Fortran編譯器不會將具有填充的COMMON塊成員對齊,但如果提供了主動優化選項,則該成員可能會更改。因此,必須確保C/C++結構具有相同的字段對齊方式,如果在Fortran方面使用了優化方法。 –

6

如果要在C和Fortran之間共享全局變量,最好的方法是使用模塊變量和Fortran ISO_C_Binding。公用塊是遺留的,除非遺留代碼的一部分,否則最好避免。使用ISO_C_Binding將使您的代碼編譯器和平臺無關。在gfortran手冊的「混合語言編程」一章的「互操作性全局變量」小節中有一個代碼示例。這不是特定於gfortran,只是一些很好的文檔。

繼續使用ISO_C_Binding,如果使用它提供的Fortran類型,將確保與C類型匹配。 Fortran相當於C的intC_INT。列表顯示在gfortran手冊的「內在模塊」一章中。

+2

不幸的是,有數以百萬計的FORTRAN 77代碼遺蹟,並不總是可以在Fortran 2003中重寫它。 –

+0

我並不反對這個,但是呃,它以相當謹慎的方式回答了horstmann的問題。 – user7116

0

thak你都爲你有用的肛門。根據你的建議,我終於意識到我的問題是什麼。我覺得我的錯誤是,Fortran中我有:

integer a(5),b 
common /sample/ a,b 

a(5)有一個固定的大小,然後在C++:

extern "C"{ 
    extern struct{ 
     int *a,b; 
}sample_; 

*a沒有大小,作爲一個指針。因此,編譯器是這樣理解的,因爲*int指針代替a(5)指針

+0

歡迎來到StackOverflow!鑑於他們的答案解決了您的問題,您應該接受[Christopher's](http://stackoverflow.com/a/10482608/7116)或[Joe's](http://stackoverflow.com/a/10482194/7116)回答。您可以點擊旁邊的複選標記來完成此操作。 – user7116