![](/img/trans.png)
[英]Call C/C++ code form a fortran program in visual studio? (How to compile mixed C and fortran code in visual studio)
[英]minimum modification to make a visual studio FORTRAN-C mixed code gfortran-gcc compatible
我正在嘗試修改此代碼 ( gist as back up )以成為gfortran-gcc兼容。
[VALUE]
標簽 -fcray-pointer
標志的POINTER
用於gfortran,而不是[REFERENCE]
標簽 __stdcall
,因為嘗試了#define __stdcall __attribute__((stdcall))
導致warning: 'stdcall' attribute ignored [-Wattributes]
現在這就是我所擁有的: C代碼CMAIN.C
:
#include <stdio.h>
extern int FACT_(int n);
extern void PYTHAGORAS_(float a, float b, float *c);
main()
{
float c;
printf("Factorial of 7 is: %d\n", FACT_(7));
PYTHAGORAS_(30, 40, &c);
printf("Hypotenuse if sides 30, 40 is: %f\n", c);
}
FORTRAN代碼FORSUBS.FOR
:
INTEGER*4 FUNCTION Fact (n)
INTEGER*4 n
INTEGER*4 i, amt
amt = 1
DO i = 1, n
amt = amt * i
END DO
Fact = amt
END
SUBROUTINE Pythagoras (a, b, cp)
REAL*4 a
REAL*4 b
POINTER (cp, c)
REAL*4 c
c = SQRT (a * a + b * b)
END
Makefile
:
all:
gfortran -c FORSUBS.FOR -fcray-pointer
gcc -c CMAIN.C
gfortran -o result.out FORSUBS.o CMAIN.o
rm -rf *.o
clean :
rm -rf *.out *~ *.bak *.o
但是我仍然得到錯誤:
CMAIN.o:在函數`main'中:
CMAIN.C :(。text + 0x1d):對'FACT_(int)'的未定義引用
CMAIN.C :(。text + 0x4c):未定義引用`PYTHAGORAS_(float,float,float *)'
如果你能幫助我,我將不勝感激:
Fortran通過引用傳遞變量,如任何Fortran到C教程的第一句中所述。 那么你:
不能只刪除[VALUE]
,你應該添加現代VALUE屬性或更改C代碼來傳遞指針。
不應該在[REFERENCE]
的Fortran端使用指針,而只是刪除它。
使用編譯器的實際名稱mangling,這些天通常是subroutine_name_
(附加的下划線,name是小寫)或使用現代bind(C, name="binding_name")
屬性。
沒有現代Fortran,但有VALUE
(它只是沒有PITA):
INTEGER*4 FUNCTION Fact (n)
INTEGER*4, VALUE :: n
INTEGER*4 i, amt
amt = 1
DO i = 1, n
amt = amt * i
END DO
Fact = amt
END
SUBROUTINE Pythagoras (a, b, c) bind(C)
REAL*4, VALUE :: a
REAL*4, VALUE :: b
REAL*4 c
c = SQRT (a * a + b * b)
END
而不僅僅是將你的C名改為小寫( pythagoras_
, fact_
)......使用VALUE
屬性,你不需要介紹你在另一個答案中看到的所有那些臨時代碼。 VALUE
需要bind(C)
才能正常工作。 它將避免您重寫調用Fortran過程的代碼。
為了獲得最佳的現代體驗,請使用bind(C,name="any_name_you_want")
來設置確切的鏈接符號名稱。
除了我的熱門評論之外,Fortran還通過引用傳遞,因此您必須修改.c
和.for
文件。
以下代碼有效。 可能有一種更簡單的方式來聲明事物,但這應該[至少]讓你更進一步。 警告 :自Fortran IV以來,我沒有做太多的事情,所以我有點生疏了。 我會推遲弗拉基米爾的VALUE
解決方案作為一種更好的方式。
#include <stdio.h>
#if 0
extern int fact_(int n);
extern void pythagoras_(float a, float b, float *c);
#else
extern int fact_(int *n);
extern void pythagoras_(float *a, float *b, float *c);
#endif
int
main(void)
{
float c;
#if 0
printf("Factorial of 7 is: %d\n", fact_(7));
#else
int n = 7;
printf("Factorial of 7 is: %d\n", fact_(&n));
#endif
#if 0
pythagoras_(30, 40, &c);
#else
float a = 30;
float b = 40;
pythagoras_(&a, &b, &c);
#endif
printf("Hypotenuse if sides 30, 40 is: %f\n", c);
return 0;
}
INTEGER*4 FUNCTION Fact (n)
INTEGER*4 n
INTEGER*4 i, amt
amt = 1
DO i = 1, n
amt = amt * i
END DO
Fact = amt
END
SUBROUTINE Pythagoras (a, b, c)
REAL*4 a
REAL*4 b
REAL*4 c
c = SQRT (a * a + b * b)
END
這是程序輸出:
Factorial of 7 is: 5040
Hypotenuse if sides 30, 40 is: 50.000000
更新:
我從你的代碼中得到了相同的
undefined reference
錯誤!
啊哈!
我沒有提到的一件事[因為我認為它不會產生影響]是我改變了源文件名以使用全部小寫字母(例如CMAIN.C --> cmain.c
和FORSUBS.FOR --> forsubs.for
)
這樣, nm *.o
的輸出產生:
cmain.o:
U fact_
0000000000000000 T main
U printf
U pythagoras_
forsubs.o:
0000000000000000 T fact_
0000000000000045 T pythagoras_
fortran源文件名的更改並不重要。 但是,C源文件名呢!
更重要的是它是文件名后綴 (即.C
更改為.c
)。
這是因為gcc
將[嘗試智能]並查看后綴以確定文件所寫的語言並進行相應編譯。 例如, gcc -c foo.cpp
將編譯該文件,就好像它是用c++
而不是 c
編寫的,就好像命令是: g++ -c foo.cpp
雖然.cpp
[更多]通常后綴為一個c++
文件名,一個備用后綴c++
文件是: .C
也就是說,大多數項目使用.cpp
約定,但有些使用.C
約定。 偏愛.cpp
不是.C
的原因之一是Windows文件系統不區分大小寫。 所以, .C
和.c
看起來是一樣的。 但是,POSIX系統(例如linux,macOSX,iOS,android等)具有區分大小寫的文件名,因此可以使用任何約定。
所以, gcc -c CMAIN.C
將編譯為c++
。 這樣做c++
風格的“名稱錯誤”符號 - 不是我們想要的。 在c++
,完成修改以允許“重載”函數名稱。 也就是說,兩個[或更多]不同的函數可以具有相同的名稱,只要它們使用不同的參數即可。 例如:
void calc(int val);
void calc(int val1,int val2);
void calc(double fval);
如果我們使用CMAIN.C
這是nm *.o
的輸出:
CMAIN.o:
0000000000000000 T main
U printf
U _Z11pythagoras_PfS_S_
U _Z5fact_Pi
FORSUBS.o:
0000000000000000 T fact_
0000000000000045 T pythagoras_
通過c++filt
運行該文件以“demangle”我們得到的c++
名稱:
CMAIN.o:
0000000000000000 T main
U printf
U pythagoras_(float*, float*, float*)
U fact_(int*)
FORSUBS.o:
0000000000000000 T fact_
0000000000000045 T pythagoras_
因此,盡可能使用小寫文件名[建議的最佳做法]。 但是,至少,不要使用.C
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.