之前可能已经提出过这个问题。我无法在搜索中找到它。
我试图在我的代码中链接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
,这是我得到的错误。
答案 0 :(得分:0)
好吧,所以,与我最初的想法相反,你的程序是一个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 ++中,每个函数都被赋予一个错误的名称&#34;它编码原型。如果您执行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"
}
而不仅仅是裸#include
。 extern "C" { ... }
构造告诉C ++编译器不将名称修改应用于其中声明的内容。因此,当您以这种方式编译时,您的程序会查找名为perf_setup_list_events
而不是_Z22perf_setup_list_eventsPKcPP17perf_event_desc_tPi
的符号,并且它会成功链接。