main的多重定义:将fortran与C ++连接起来

时间:2011-10-17 00:55:20

标签: c++ macos gfortran

我想编写一个C ++程序来调用

中的mvndst_()子例程

http://www.math.wsu.edu/faculty/genz/software/fort77/mvndstpack.f

在Linux上,如果我创建test.cc:

extern "C" {
    int mvndst_(int *, double *, double *, int *, double *, int *,
                double *, double *, double *, double *, int *);
};
int main() {
    return 0;
}

并通过

编译
g++ -c -o test.o test.cc
gfortran -c -o mvndstpack.o mvndstpack.f
gfortran -Mnomain -o test test.o mvndstpack.o

然后我得到

mvndstpack.o: In function `main':
mvndstpack.f:(.text+0x4a2a): multiple definition of `main'
test.o:test.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status

但是,如果我在链接之前运行strip -N main mvndstpack.o,那么链接会成功。有人可以解释为什么-Mnomain标志在这里不起作用?我还想避免使用“strip”的解决方案,因为Mac OS X上“strip”的行为似乎不同(即,-N选项不可用,我不确定另一种方式获得正确的行为)。如果可能的话,我还想避免编辑原始的Fortran源代码。

详细说明: - GNU Fortran(Ubuntu / Linaro 4.6.1-9ubuntu3)4.6.1 - g ++(Ubuntu / Linaro 4.6.1-9ubuntu3)4.6.1 - GNU strip(Ubuntu的GNU Binutils)2.21.53.20110810 - 在Mac OS X 10.6 Snow Leopard上剥离

2 个答案:

答案 0 :(得分:4)

我找不到-Mnomain选项的任何文档,但gfortran没有抱怨它(似乎将它传递给链接器)。但是当我跑步时它也没有抱怨

gfortran -Mnoplatypus -o test test.o mvndstpack.o

所以我的猜测是它不支持-Mnomain,并且它被默默地忽略了。 (要么是,要么有-Mnoplatypus选项,但这似乎不太可能。)

对我有用的是在PROGRAM TSTNRM(第15到62行)中注释END .. mvndstpack.f行。

无论如何,这可能是最明智的做法;你不想使用Fortran主程序,所以你也可以不编译它,而不是试图欺骗链接器忽略它。

(如果您愿意,可以使用#if ... #endif#ifdef ... #endif。)

修改

由于您的主程序是使用C ++,因此您可能需要使用g++而不是gfortran来创建可执行文件:

g++ -c -o test.o test.cc
gfortran -c -o mvndstpack.o mvndstpack.f
g++ -o test test.o mvndstpack.o

(在某些时候你真的想要调用这个函数。)

答案 1 :(得分:2)

您的问题是FORTRAN代码也包含main,只是在那个世界中它被称为PROGRAM。来自 mvndstpack.f

      PROGRAM TSTNRM
*
*     Test program for MVNDST
*

你需要选择围栏的哪一侧将首先举办派对!

在这种情况下,您希望C ++调用FORTRAN,因此您只需要抛弃包含TSTNRM程序的FORTRAN文件的顶部,或将其包装在条件编译部分中:

#if TEST
      PROGRAM TSTNRM
...
      END
#endif

然后,您可以将文件重命名为(case cases)mvndstpack.Fmvndstpack.FPP,或者在命令行选项中使用-cpp gfortran。