【问题标题】:Multiple definition of main: linking fortran with C++main的多重定义:用C++链接fortran
【发布时间】:2011-10-17 00:55:19
【问题描述】:

我想编写一个从

调用 mvndst_() 子例程的 C++ 程序

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 条(用于 Ubuntu 的 GNU Binutils)2.21.53.20110810 - 在 Mac OS X 10.6 Snow Leopard 上剥离

【问题讨论】:

    标签: c++ macos gfortran


    【解决方案1】:

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

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

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

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

    无论如何,这可能是最明智的方法;你不想使用 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
    

    (在某些时候,您实际上会想要调用该函数。)

    【讨论】:

    • 谢谢,有道理!我不知何故认为应该有一种方法可以在不编辑 Fortran 源代码的情况下做到这一点……但我想可能不是。
    【解决方案2】:

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

          PROGRAM TSTNRM
    *
    *     Test program for MVNDST
    *
    

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

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

    #if TEST
          PROGRAM TSTNRM
    ...
          END
    #endif
    

    然后您可以将文件重命名为(大小写)mvndstpack.Fmvndstpack.FPP,或者在 gfortran 的命令行选项上使用 -cpp

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-15
      • 1970-01-01
      • 2019-04-05
      相关资源
      最近更新 更多