问题描述
我有一个关于混合语言编程(C / C ++和Fortran)问题
使用gcc和gfortran。我搜索很多混合FORTRAN与
语言X并没有能够解决这个问题。
I have a question about mixed-language programming (C/C++ and FORTRAN)using gcc and gfortran. I've searched plenty of "mixing fortran withlanguage X" and haven't been able to resolve this.
我不知道这是否是一个连接问题或编译器的问题,或者两者兼而有之。
I'm not sure if this is a linking problem or a compiler problem, or both.
我已经创建了三个文件,我利用GNU autotools构建
原油应用,而应该是能够建立从命令的应用程序
行独立。
I've created three files and I'm using GNU Autotools to build thecrude application, but should be able to build the app from commandline independently.
C文件(main.c中),将驱动应用程序,调用数
FORTRAN功能:
The C File (main.c) will be the driving app, that calls severalFORTRAN functions:
/* this is a simple program */
#include <stdio.h>
/* add the extern function definition */
#include "fooonly.h"
// this is not working for the mixed language programming stuff yet...
/* this is the main program section */
int main( int argc, char *argv[] )
{
int a = 36;
int b = 24;
int c = 0;
printf( "hi mom\n" );
/* now call a FORTRAN function from C */
c = NGCD( &a, &b );
printf( "NGCD(%d,%d)=%d\n", a, b, c );
return 0;
}
在Fortran函数将最常包含FORTRAN 77(但
还可以包括FORTRAN90 / 95 code太),是这样的:
The fortran function which will most often contain FORTRAN 77 (butcan also include FORTRAN90/95 code too), looks like:
c$$$ The following introductory example in FORTRAN 77 finds the
c$$$ $ greatest common divisor for two numbers A and B using a
c$$$ $ verbatim implementation of Euclid's algorithm.
FUNCTION NGCD(NA, NB)
IA = NA
IB = NB
1 IF (IB.NE.0) THEN
ITEMP = IA
IA = IB
IB = MOD(ITEMP, IB)
GOTO 1
END IF
NGCD = IA
RETURN
END
使用开发。工作室6 /康柏数字的Fortran 6.0,这工作正常。在
其实,我没有使用的#define __cplusplus的ifdef /#ENDIF和CAN
只需创建一个C文件,看起来像:
Using Dev. Studio 6/Compaq Digital Fortran 6.0, this works fine. Infact, I don't have to use the #define ifdef __cplusplus/#endif and cansimply create a C file that looks like:
/* this is a simple program */
#include <stdio.h>
/* add the extern function definition */
extern "C" int __stdcall NGCD( int *a, int *b );
/* this is the main program section */
int main( int argc, char *argv[] )
{
int a = 36;
int b = 24;
int c = 0;
printf( "hi mom\n" );
/* now call a FORTRAN function from C */
c = NGCD( &a, &b );
printf( "NGCD(%d,%d)=%d\n", a, b, c );
return 0;
}
和与上面的FORTRAN编译上市它的应用程序链接,
运行,并产生正确的结果。
and compile it with the FORTRAN listing above, the application links,runs, and generates the correct results.
C:\fooonly>fooonly.exe
hi mom
NGCD(36,24)=12
C:\fooonly>
当我尝试顶部重复使用的MinGW的或GNU Autotools的这个过程
OSX,我继续得到以下错误:
When I try top repeat this process using GNU Autotools on MinGW orOSX, I continue to get the following errors:
macbook:makecheck $ make
gcc -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"fooonly\" -DVERSION=\"1.0.2\" -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
mv -f .deps/main.Tpo .deps/main.Po
gfortran -g -O2 -o fooonly main.o ngcd.o
Undefined symbols for architecture x86_64:
"_NGCD", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [fooonly] Error 1
macbook:makecheck $
其中Makefile文件(由GNU自动工具产生的),基本上包含
下面的命令:
where the Makefile (generated by GNU Autotools), basically containsthe following commands:
macbook:makecheck $ gcc -c main.c
macbook:makecheck $ gfortran -c ngcd.f
macbook:makecheck $ gcc -o fooonly main.c ngcd.o
Undefined symbols for architecture x86_64:
"_NGCD", referenced from:
_main in cc9uPBWl.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
macbook:makecheck $
我的configure.in脚本中包含有总比没有更多:
My configure.in script contains nothing more than:
AC_INIT(main.c)
AM_INIT_AUTOMAKE(fooonly, 1.0.2)
## C/C++ compiler section
AC_PROG_CC
## fortran section
AC_PROG_F77
## output section
AC_OUTPUT(Makefile)
这基本上是,
macbook:makecheck $ gcc -c main.c
macbook:makecheck $ gfortran -c ngcd.f
macbook:makecheck $ gcc -o fooonly main.c ngcd.o
吧?
我试图建立这种多平台(Linux的Win32 / 64,OSX,
等),并希望使用GNU Autotools的,我知道这是用做
其他开源项目,但对于那些configure.in脚本
项目远远超出我的GNU Autotools的新手排骨和我得到一个
有点不知所措试图去code它们。
I'm trying to build this on multiple platforms (Linux, Win32/64, OSX,etc.) and wish to use GNU Autotools, and I know this is done withother open-source projects, but the configure.in scripts for thoseprojects are way beyond my GNU Autotools newbie chops and I get alittle overwhelmed trying to decode them.
我猜这事做有:
1)我在configure.in脚本中使用的定义,
2)我不包括一些神奇的一组交换机
(即-fno秒下划线),或
3)两个的某些组合
1) The definitions I've used in the configure.in script,2) I'm not including some magical set of switches(i.e. -fno-second-underscore?), or3) Some combination of the two?
我是否关闭,如果是这样,我怎么应用程序建立?
Am I close and if so, how do I get the app to build?
推荐答案
只要你有一个较新的编译器那么过去几年,我建议使用ISO C绑定到的Fortran与其他语言混合。然后,你可以跳过名称用下划线和类似的编译器/平台相关的问题,重整。如果你有传统的FORTRAN 77 code,你不想改变,你可以写C和FORTRAN的旧77.指令描述previous方法,需要的更多的理解之间的一个小的Fortran 2003常规胶内部接口和更编译器/平台相关的。对于新的方法,看一下gfortran手册第四章混合语言编程和previous问题/答案在这里。
As long as you have a compiler newer then the past several years, I recommend using the ISO C Binding to mix Fortran with other languages. Then you can skip the name mangling with underscores and similar compiler/platform dependent issues. If you have legacy FORTRAN 77 code that you don't want to alter, you could write a small Fortran 2003 glue routine between the C and the FORTRAN 77. Older instructions describe the previous method which required more understanding of the internal interfaces and was more compiler/platform dependent. For the new method, look at the gfortran manual chapter "Mixed Language Programming" and previous questions/answers here.
使用Fortran的code更容易与gfortran联系起来,因为,在Fortran运行时库带来的。我认为同样适用于C ++,所以如果你有两个你必须明确地包含一种或另一种的运行时库。
With Fortran code it is easier to link with gfortran because that brings in the Fortran runtime libraries. I think that the same applies to C++, so if you have both you will have to explicitly include the runtime library of one or the other.
P.S。下面是使用Fortran的ISO C绑定一个例子:
P.S. Here is an example using the Fortran ISO C Binding:
function NGCD (na, nb) bind (C, name="NGCD")
use iso_c_binding
implicit none
integer (c_int) :: ngcd
integer (c_int), intent (in) :: na, nb
integer (c_int) :: ia, ib, itemp
ia = na
ib = nb
do while (ib /= 0)
itemp = ia
ia = ib
ib = mod(itemp, ib)
end do
ngcd = ia
return
end function NGCD
与编译/链接:
gcc -c main.c
gfortran main.o ngcd.f90
这篇关于C / C ++,FORTRAN,下划线和GNU自动工具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!