我想编写一个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上剥离
答案 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.F
或mvndstpack.FPP
,或者在命令行选项中使用-cpp
gfortran。