要从C ++调用Fortran例程,我一直在使用: extern "C" void routinename_(...) 附加下划线使其与Fortran子程序名称“ROUTINENAME”兼容。
当我将c ++链接到BLAS或LAPACK时,仅在没有下划线的情况下才有效。链接c ++与这些Fortran编写的库之间有什么区别,使下划线不必要?
可能是我错了,因为很少有信息可以依据,但是...
从这里:最初的F77编译器会在ABI中将函数名称附加一个_
。这种行为与C不同,C只需使用函数名并将其用作ABI中的名称即可。
一些F77编译器的行为不同,它们会将整个子程序名称大写,因此当被C查看时,foo()
变成FOO()
。UNIX Fortran编译器模仿C的行为,仅复制-粘贴名称,以使foo()
在ABI中也是foo()
。
但是,如果您查看BLAS绑定到C的参考实现这里,您会发现它们在处理与F77交互时会处理尾随下划线。我敢打赌,在过去,下划线比没有下划线更常见。
后来,Fortran 2003 引入了与 C 的互操作性(请参见此处)。当使用某些 Fortran 构造时,这使得函数命名方案相同(请参见此处)。
因此,我猜测这与 Fortran 版本之间的 ABI 差异有关。甚至只是在不同编译器之间,因为不同的编译器在 Fortran 中似乎有不同的行为。
所以,再次强调,我不确定这是否与您的情况匹配,因为您的问题中没有太多信息,但我无法将所有内容都放在评论中,所以这里作为一个“答案”。
如果我错了,请告诉我,这样我就可以更正我的帖子。
简而言之:由于编译器版本。
我将提供一个通用的BLAS链接答案,不仅适用于这个问题,该问题的答案在下面。
首先,您需要确保已安装BLAS(+lapack)
$ sudo apt-get install libblas-dev liblapack-dev
然后,您可以在程序文件后使用-lblas进行链接。或者您可以使用makefile。
例如: g++ test.o dmatrix_denseCM.o mmio.o -o output -lblas
从我的角度来看,我更喜欢使用OpenBlas,您可以在makefile中使用以下内容。
完成后,您应该有文件libopenblas.a,即openblas库
这个目录 OpenBLAS/libopenblas.a 应该在同一个工作目录中。
.cc 文件中的示例代码:
extern "C"{
void dgemm_( const char &TRANSA, const char &TRANSB, const int &M, const int &N, const int & K, const double & ALPHA, const double *A, const int & LDA, const double *B, const int &LDB, const double &BETA, double *C, const int & LDC);
}
Fortran编译器通常会在入口点定义和调用中出现的子程序名称后附加下划线(_)。这种约定与具有相同用户分配名称的C过程或外部变量不同。在这里。
C ++中的名称混淆会导致C中的问题。由于C不支持重载,因此我们必须使用extern "c" {}。
LAPACKE
(Lapack 的 C 接口)吗?还有一个 C 接口可以连接到 BLAS。 - Stefan