对函数的未定义引用

undefined reference to a function c

本文关键字:引用 未定义 函数      更新时间:2023-10-16

这个问题以前可能有人问过。我怎么找也找不到。

我试图链接libpfm4.5.0在我的代码。我使用的头文件如下:perf_util.h

libpfm4.5.0的下载链接

在哪里包含头文件很重要吗?

下面是我的代码片段:

#include "matrix.h"
#include "perf_util.h"
int read_counts(int pid, int app_num){
    int ret, i, num_fds = 0, grp, group_fd;
    int ready[2], go[2];
    char buf;
    int nevents;
    nevents = TOTAL_NUM_EVENTS;
    go[0]=go[1] = -1;
    for (grp = 0; grp < nevents; grp++) {
        int ret;
        ret = perf_setup_list_events(perf_events.pmc[grp], &fds_pid[app_num], &num_fds);
        if (ret || !nevents)
            exit(1);
    }
   }

头文件perf_util.h包含perf_setup_list_events函数,但在编译过程中

matrix.o: In function `read_counts(int, int)':
matrix.c:(.text+0xf20): undefined reference to `perf_setup_list_events(char const*, perf_event_desc_t**, int*)'
collect2: error: ld returned 1 exit status

是我得到的错误。我可能会在哪些地方出错?如有任何帮助,不胜感激。

我是这样编译的

g++ -I. -I/libpfm-4.5.0/perf_examples/../include -DCONFIG_PFMLIB_DEBUG -DCONFIG_PFMLIB_OS_LINUX -I. -D_GNU_SOURCE -pthread -w -c matrix.c
g++ -I. -I/libpfm-4.5.0/perf_examples/../include -DCONFIG_PFMLIB_DEBUG -DCONFIG_PFMLIB_OS_LINUX -I. -D_GNU_SOURCE -pthread -w -o matrix matrix.o perf_util.o /libpfm-4.5.0/perf_examples/../lib/libpfm.a 

注意:libpfm使用cc编译,我使用g++。这是问题所在吗?如果是,我该如何解决?

下面是我现在如何编译它:

cc -std=c99 -I. -I/libpfm-4.5.0/perf_examples/../include -DCONFIG_PFMLIB_DEBUG -DCONFIG_PFMLIB_OS_LINUX -I. -D_GNU_SOURCE -pthread -w -c matrix.c 
cc -std=c99 -I. -I/libpfm-4.5.0/perf_examples/../include -DCONFIG_PFMLIB_DEBUG -DCONFIG_PFMLIB_OS_LINUX -I. -D_GNU_SOURCE -pthread -w -o matrix matrix.o perf_util.o libpfm-4.5.0/perf_examples/../lib/libpfm.a 

error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token 
const char * pmc[TOTAL_NUM_EVENTS] = {"blah", "blahbar"}

我有一个const char * array,这是我得到的错误。

好,所以,与我一开始的想法相反,你的程序一个c++程序。我们知道这种情况,因为c++编译器接受它,而C编译器不接受。(你仍然没有给我足够的信息来理解为什么 C编译器不喜欢它,但我怀疑这是一些无意思的东西,就像定义一个不能在编译时完全初始化的文件作用域变量一样。如果你的意思是这是一个C程序,你应该问一个新的问题。无论如何。)

您正在使用的库是C,而不是c++,并且它的头文件没有设置为从c++程序中使用。我从错误消息推断出这就是问题所在:

undefined reference to `perf_setup_list_events(char const*, perf_event_desc_t**, int*)'

看看这个错误信息是如何给出函数perf_setup_list_events的完整原型的?这是因为c++有函数重载,而C没有——所以,在c++中,每个函数都有一个"扭曲的名字",用来编码它的原型。如果您执行nm matrix.o | grep perf_setup_list_events,您将发现这个混乱的名称:它可能类似于_Z22perf_setup_list_eventsPKcPP17perf_event_desc_tPi。链接器会将其解码为原型。

因此,链接器错误有一个完整的原型,本身,这一事实告诉我,未定义的引用来自编译为c++的代码。现在,我以前从未听说过libpfm4.5.0,但我知道,如果您的库实际上没有定义该函数,那么您将得到一个不同的错误消息——例如

错误:' perf_setup_list_events '未在此范围内声明

所以我猜这个库是用C写的,而不是c++,而且它的头文件不是用来处理从c++程序中使用的。这是标准库中的一个缺陷,但是可以通过写入

来解决。
extern "C" {
#include "perf_util.h"
}

而不是仅仅是#includeextern "C" { ... }结构告诉c++编译器而不是对其中声明的任何内容应用名称混淆。因此,当以这种方式编译时,您的程序将查找名为perf_setup_list_events而不是_Z22perf_setup_list_eventsPKcPP17perf_event_desc_tPi的符号,并成功链接。