2014-09-30 4 views
-2

Я пытаюсь скомпилировать программу на C, которая использует libvncserver, но независимо от того, что я делаю, я продолжаю получать ошибки undefined reference, у библиотеки, с которой я столкнулся, есть rfb/rfb.h.Неопределенная ссылка на ... при связывании заголовка библиотеки

код vnc.c (копируется из here):

#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); 
} 

выход Компилятор:

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 

У меня libvncserver0 и установил libvncserver-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 

Но я получаю те же ошибки каждый раз. Что я делаю неправильно и как я могу это исправить?

+3

Вместо случайного использования разных вариантов, почему бы вам не прочитать руководство и узнать, что означают опции? –

+0

Hi razzak. Я исправил этот вопрос, в частности, связанный с удалением комментариев для голосования. Поскольку вы вернулись, я сниму, и если вы снова вернетесь, я буду отмечать модератора. «Пожалуйста, не уменьшайте» сообщения не интересуют читателей - если вы хотите прокомментировать голосование, добавьте комментарий (и, на мой взгляд, они могут поощрять больше downvotes, поэтому я думаю, что это пустая трата времени). – halfer

ответ

7

Вы не заголовок библиотеки «ссылки», вы включаете так компилятор видит заявления библиотечных во время компиляции и знает, что rfbGetScreen() это функция, которая принимает так-то много аргументов этого -and-type и возвращает rfbScreenInfoPtr. Как он делает это (определение функции) не имеет значения для компилятора. Он просто добавляет ссылку на эту функцию, которая остается для решения компоновщика. (Обратите внимание на словарный запас здесь.)

Вы ссылку ваш скомпилированный код в библиотеку двоичный. Это делается компоновщиком в другом (и более позднем) шаге, который имеет, который будет поддерживаться тем же интерфейсом, что и компиляция источника (gcc). На этом этапе любая из функций библиотеки, которую на самом деле использует ваш код , содержит (ссылки): разрешен, связав их в указанных библиотеках.

Это здесь ...

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

... ссылки только стандартные библиотеки и исполнения, так как не существует никаких конкретных инструкций соединительные там.

Это здесь ...

-L/usr/include/rbf/rfb.h 

... это нонсенс, так как -L для предоставления директорий, где библиотека двоичные файлы следует искать (и не надо, если библиотека в вопросе установлена ​​в стандартное местоположение).

Фактическая ссылка: -l. Если вы укажете -lfoo, то в библиотеке libfoo будут найдены любые неопределенные ссылки.

Это здесь ...

-ldl 

... связывает libdl, и от этого вы должны быть в состоянии сделать вывод, что ...

-lvncserver 

... это то, что вы ищете (если предположить, что <rfb/rfb.h> на самом деле относятся к libvncserver, что я не знаю).

Обратите внимание, что компоновщик обрабатывает библиотеки в последовательности они заданы в командной строке, так что вы должны заявить -lvncserverпослеvnc.c, потому что только тогда компоновщик знает какие неопределенных ссылок он должен искать для в libvncserver.

И никогда, запустить компилятор как sudo. Почему в названии {.....} вы считаете, что это необходимо?

+0

это дало те же ошибки, что и выше. – razzak

+1

Убедитесь, что вы положили '-lvncserver' после' vnc.c' и просто чтобы повторить важную точку: ** никогда не запускайте компилятор с 'sudo' ** –

+0

Я побежал:' gcc -g -Wall -Wextra -O2 -lvncserver vnc.c' и получил те же неопределенные ошибки ссылок! – razzak