"cblas_ddot"未定义的引用

本文介绍如何在C++程序中正确调用CBLAS库中的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_comatcopy的相关信息,下面从通用的BLAS(Basic Linear Algebra Subprograms)库函数角度进行推测性介绍。 ### 功能介绍 通常,BLAS库中的函数命名遵循一定的规律,“copy”相关的函数一般是用于数据复制操作。推测cblas_comatcopy函数可能用于将一个复矩阵(复数矩阵)的元素复制到另一个复矩阵中。这里的“co”可能代表“complex”(复数),“mat”代表“matrix”(矩阵)。 ### 使用方法 一般BLAS函数会有一些标准的参数,对于cblas_comatcopy函数,可能的参数和使用示例如下: ```c // 假设函数原型如下 void cblas_comatcopy( const enum CBLAS_ORDER Order, // 矩阵的存储顺序,如CBLAS_ROW_MAJOR或CBLAS_COL_MAJOR const int M, // 矩阵的行数 const int N, // 矩阵的列数 const MKL_Complex16 *A, // 源复矩阵 const int lda, // 源矩阵的 leading dimension MKL_Complex16 *B, // 目标复矩阵 const int ldb // 目标矩阵的 leading dimension ); ``` 使用示例: ```c #include <stdio.h> #include <mkl_cblas.h> #define M 3 #define N 3 int main() { MKL_Complex16 A[M * N]; MKL_Complex16 B[M * N]; // 初始化源矩阵A for (int i = 0; i < M * N; i++) { A[i].real = (double)i; A[i].imag = (double)(i + 1); } // 调用cblas_comatcopy函数 cblas_comatcopy(CBLAS_ROW_MAJOR, M, N, A, N, B, N); // 输出目标矩阵B for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { printf("B[%d][%d] = (%f, %f)\n", i, j, B[i * N + j].real, B[i * N + j].imag); } } return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值