链接库标题时未定义的引用....

raz*_*zak -2 c linker gcc

我正在尝试编译一个使用的C程序,libvncserver但无论我做什么我都会遇到undefined reference错误,我遇到麻烦的库是rfb/rfb.h.

vnc.c代码(从这里复制):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rfb/rfb.h>
#define WIDTH 640
#define HEIGHT 480
#define BPP 4
/* 15 frames per second (if we can) */
#define PICTURE_TIMEOUT (1.0/15.0)
/*
* throttle camera updates
*/
int TimeToTakePicture() {
static struct timeval now={0,0}, then={0,0};
double elapsed, dnow, dthen;
gettimeofday(&now,NULL);
dnow = now.tv_sec + (now.tv_usec /1000000.0);
dthen = then.tv_sec + (then.tv_usec/1000000.0);
elapsed = dnow - dthen;
if (elapsed > PICTURE_TIMEOUT)
memcpy((char *)&then, (char *)&now, sizeof(struct timeval));
return elapsed > PICTURE_TIMEOUT;
}
/*
* simulate grabbing a picture from some device
*/
int TakePicture(unsigned char *buffer)
{
static int last_line=0, fps=0, fcount=0;
int line=0;
int i,j;
struct timeval now;
/*
* simulate grabbing data from a device by updating the entire framebuffer
*/
for(j=0;j<HEIGHT;++j) {
for(i=0;i<WIDTH;++i) {
buffer[(j*WIDTH+i)*BPP+0]=(i+j)*128/(WIDTH+HEIGHT); /* red */
buffer[(j*WIDTH+i)*BPP+1]=i*128/WIDTH; /* green */
buffer[(j*WIDTH+i)*BPP+2]=j*256/HEIGHT; /* blue */
}
buffer[j*WIDTH*BPP+0]=0xff;
buffer[j*WIDTH*BPP+1]=0xff;
buffer[j*WIDTH*BPP+2]=0xff;
}
/*
* simulate the passage of time
*
* draw a simple black line that moves down the screen. The faster the
* client, the more updates it will get, the smoother it will look!
*/
gettimeofday(&now,NULL);
line = now.tv_usec / (1000000/HEIGHT);
if (line>HEIGHT) line=HEIGHT-1;
memset(&buffer[(WIDTH * BPP) * line], 0, (WIDTH * BPP));
/* frames per second (informational only) */
fcount++;
if (last_line > line) {
fps = fcount;
fcount = 0;
}
last_line = line;
fprintf(stderr,"%03d/%03d Picture (%03d fps)\r", line, HEIGHT, fps);
/* success! We have a new picture! */
return (1==1);
}
/*
* Single-threaded application that interleaves client servicing with taking
* pictures from the camera. This way, we do not update the framebuffer
* while an encoding is working on it too (banding, and image artifacts).
*/
int main(int argc,char** argv)
{
long usec;
rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,WIDTH,HEIGHT,8,3,BPP);
if(!server)
return 0;
server->desktopName = "Live Video Feed Example";
server->frameBuffer=(char*)malloc(WIDTH*HEIGHT*BPP);
server->alwaysShared=(1==1);
/* Initialize the server */
rfbInitServer(server);
/* Loop, processing clients and taking pictures */
while (rfbIsActive(server)) {
if (TimeToTakePicture())
if (TakePicture((unsigned char *)server->frameBuffer))
rfbMarkRectAsModified(server,0,0,WIDTH,HEIGHT);
usec = server->deferUpdateTime*1000;
rfbProcessEvents(server,usec);
}
return(0);
}
Run Code Online (Sandbox Code Playgroud)

编译器输出:

sudo gcc -g -Wall -Wextra -O2 vnc.c

/tmp/cc7dpMCs.o: In function `main':
/home/arcm/Projects/c/vnc.c:77: undefined reference to `rfbGetScreen'
/home/arcm/Projects/c/vnc.c:84: undefined reference to `rfbInitServerWithPthreadsAndZRLE'
/home/arcm/Projects/c/vnc.c:91: undefined reference to `rfbProcessEvents'
/home/arcm/Projects/c/vnc.c:86: undefined reference to `rfbIsActive'
/home/arcm/Projects/c/vnc.c:89: undefined reference to `rfbMarkRectAsModified'
collect2: error: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

我有libvncserver0libvncserver-dev安装,我使用Ubuntu 14.04.我试过了:

sudo gcc -g -Wall -Wextra -O2 vnc.c -lm
sudo gcc -g -Wall -Wextra -O2 vnc.c -ldl
sudo gcc -g -Wall -Wextra -O2 -ldl vnc.c
sudo gcc -g -Wall -Wextra -O2 -I/usr/include/rfb -L/usr/include/rbf/rfb.h vnc.c 
sudo gcc -g -Wall -Wextra -O2 -I/usr/include/rfb vnc.c
sudo gcc -g -Wall -Wextra -O2 -L/usr/include/rbf/rfb.h vnc.c
sudo gcc -g -Wall -Wextra -O2 /usr/include/rbf/rfb.h vnc.c
sudo gcc -g -Wall -Wextra -O2 -L/usr/include/rbf/rfb.h -ldl vnc.c
Run Code Online (Sandbox Code Playgroud)

但我每次都会得到同样的错误.我做错了什么,我该如何解决?

Dev*_*lar 7

你没有"链接"库头,你包含它,所以编译器在编译时看到库的声明,并且知道这rfbGetScreen()是一个函数,它接受了这个和那个类型的许多参数并返回一个rfbScreenInfoPtr.它是如何做到的(函数的定义)对编译器来说并不重要.它只是添加了对该函数的引用,留给链接器解析.(注意这里的词汇.)

将已编译的代码链接到库二进制文件.这是由链接器完成的,在不同的(以及后面的)步骤中,恰好由编译source(gcc)的同一前端支持.在此步骤中,通过从指定的库链接它们来解析代码实际使用的任何库函数(引用).

这里...

sudo gcc -g -Wall -Wextra -O2 vnc.c
Run Code Online (Sandbox Code Playgroud)

...仅链接标准库和运行时,因为那里没有特定的链接指令.

这里...

-L/usr/include/rbf/rfb.h
Run Code Online (Sandbox Code Playgroud)

...是无意义的,就像-L给出应该查找库二进制文件的目录一样(如果有问题的库安装在标准位置,则不需要).

实际的链接指令是-l.如果您声明-lfoo,则libfoo搜索库以查找任何未定义的引用.

这里...

-ldl
Run Code Online (Sandbox Code Playgroud)

...正在联系libdl,你应该能够推断......

-lvncserver
Run Code Online (Sandbox Code Playgroud)

...是你正在寻找的(假设<rfb/rfb.h>实际上是指libvncserver,我不知道).

请注意,链接器按照命令行中给出的顺序处理库,因此您需要在-lvncserver 之后 进行声明vnc.c,因为只有这样链接器才能知道它应该查找哪些未定义的引用libvncserver.

从来没有像以前那样运行编译器sudo.为什么在{.....}的名字你认为这是必要的?