"cblas_ddot"未定义的引用

#include <iostream>
extern "C" {
#include <cblas.h>
}

using namespace std;

int main(int argc, char const *argv[])
{
    double a[6] ={2.5,1.,1.5,1.,1.,1.};
    double b[5] ={2.,3.,4.,3.,2.};
    double re;
    re = cblas_ddot(2, a, 2, b, 2);
    cout << "result= " << re << endl;;
    return 0;
}

想测试cblas_ddot函数的时候,写了一句测试代码,结果报错:”cblas_ddot”未定义的引用,想了一会,才明白。
我们知道,C/C++编译为obj文件的时候并不需要函数的具体实现,只要有函数的原型即可。但是在链接为可执行文件的时候就必须要具体的实现了


  • 未声明的引用

如果错误是未声明的引用,那就是找不到函数的原型,解决办法这里就不细致说了,通常是相关的头文件未包含。

  • 未定义的引用

    在C++工程中,库是用来链接的。当C++程序被编译成对象文件.o文件时,下一步就是,链接。库分静态库.a 与共享库.so(shared objects),优先使用共享库。但是当用到共享库的时候,如果库不是安装在系统默认路径(/usr/lib /usr/local/lib),则需要将该库的路径用-L选项指定或者添加到载入路径中LD_LIBRARY_PATH,一般都选择使用环境变量LD_LIBRARY_PATH。此外还有另外两个环境变量:INCLUDE_PATH 和 LIBRARY_PATH。
    当C++程序中用到了外部库,那么如果只试图利用源文件来编译生成可执行文件,那么就会导致在链接的时候编译器报错:未定义的引用。
    注意链接次序问题。当使用gcc/g++指令来编译C++程序时,命令行上库的顺序遵照对象文件(object files)中同样的规则:它们被从左到右的搜索——包含函数定义的库应该出现在任何使用到该函数的源文件和对象文件的后面。当用到多个库时,库之间也应当遵守相同的规则。否则也会报错:未定义的引用。

  • 所以上述代码的编译指令应该为:g++ cblas_ddot.cpp -lcblas -o cblas_ddot 。输出result=11。所以cblas_ddot的第一个参数应该是从a b 中选取的元素个数,也就是从a b分别以2为步长选取2个元素做内积。

  • 但是还有一个问题:为什么相同的代码在IDE里,比如eclipseCDT就报错???作为一个问题,继续学习吧

    下面对这个问题加以解答:
    其实很简单,当使用gcc指令编译时,如g++ cblas_ddot.cpp -lcblas -o cblas_ddot,我们需要把lib显示地表示出来即使它安装在默认路径。那么在IDE中也是如此,以Nsight或者eclipseCDT为例,解决方法为:工程属性——>C/C++ Build——>Setting——>GCC C++ Linker, 选择Libraries, 将库的名字加入其中,cblas,因为该库安装在默认路径中,所以不需要在Library search Path中设置其路径。

  • 你可能感兴趣的:("cblas_ddot"未定义的引用)