[SOLVED] undefined reference to a prototype included in a header...
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
undefined reference to a prototype included in a header...
Hello,
I am trying to see why g++ is giving me this error.
Code:
rgonzale@darkstar:~1060 g++ main.cpp -luici
main.cpp: In function ‘int login()’:
main.cpp:17: warning: deprecated conversion from string constant to ‘char*’
/tmp/cchB0XrG.o: In function `login()':
main.cpp:(.text+0x24): undefined reference to `u_connect(unsigned short, char*)'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libuici.so: undefined reference to `addr2name'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libuici.so: undefined reference to `name2addr'
collect2: ld returned 1 exit status
I have two header files
uici.h
Code:
#define UPORT
typedef unsigned short u_port_t;
int u_open(u_port_t port);
int u_accept(int fd, char *hostn, int hostnsize);
int u_connect(u_port_t port, char *hostn);
I compiled uici.c into a shared library libuici.so and put it in /usr/lib64
uici.c
Code:
/* uici.c sockets implementation */
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/socket.h>
#include "uici.h"
#include "uiciname.h"
#ifndef MAXBACKLOG
#define MAXBACKLOG 50
#endif
/*
* u_igniore_sigpipe
* Ignore SIGPIPE if the default action is in effect.
*
* returns: 0 if successful
* -1 on error and sets errno
*/
static int u_ignore_sigpipe() {
struct sigaction act;
if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) == -1)
return -1;
if (act.sa_handler == SIG_DFL) {
act.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) == -1)
return -1;
}
return 0;
}
/*
* u_open
* Return a file descriptor, which is bound to the given port.
*
* parameter:
* s = number of port to bind to
* returns: file descriptor if successful
* -1 on error and sets errno
*/
int u_open(u_port_t port) {
int error;
struct sockaddr_in server;
int sock;
int true = 1;
if ((u_ignore_sigpipe() == -1) ||
((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1))
return -1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&true,
sizeof(true)) == -1) {
error = errno;
while ((close(sock) == -1) && (errno == EINTR));
errno = error;
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons((short)port);
if ((bind(sock, (struct sockaddr *)&server, sizeof(server)) == -1) ||
(listen(sock, MAXBACKLOG) == -1)) {
error = errno;
while ((close(sock) == -1) && (errno == EINTR));
errno = error;
return -1;
}
return sock;
}
/*
* u_accept
* Wait for a connection request from a host on a specified port.
*
* parameters:
* fd = file descriptor previously bound to listening port
* hostn = a buffer that will hold the name of the remote host
* hostnsize = size of hostn buffer
* returns: a communication file descriptor on success
* hostn is filled with the name of the remote host.
* -1 on error with errno set
*
* comments: This function is used by the server to wait for a
* communication. It blocks until a remote request is received
* from the port bound to the given file descriptor.
* hostn is filled with an ASCII string containing the remote
* host name. It must point to a buffer of size at least hostnsize.
* If the name does not fit, as much of the name as is possible is put
* into the buffer.
* If hostn is NULL or hostnsize <= 0, no hostname is copied.
*/
int u_accept(int fd, char *hostn, int hostnsize) {
int len = sizeof(struct sockaddr);
struct sockaddr_in netclient;
int retval;
while (((retval =
accept(fd, (struct sockaddr *)(&netclient), &len)) == -1) &&
(errno == EINTR))
;
if ((retval == -1) || (hostn == NULL) || (hostnsize <= 0))
return retval;
addr2name(netclient.sin_addr, hostn, hostnsize);
return retval;
}
/*
* u_connect
* Initiate communication with a remote server.
*
* parameters:
* port = well-known port on remote server
* hostn = character string giving the Internet name of remote host
* returns: a communication file descriptor if successful
* -1 on error with errno set
*/
int u_connect(u_port_t port, char *hostn) {
int error;
int retval;
struct sockaddr_in server;
int sock;
fd_set sockset;
if (name2addr(hostn,&(server.sin_addr.s_addr)) == -1) {
errno = EINVAL;
return -1;
}
server.sin_port = htons((short)port);
server.sin_family = AF_INET;
if ((u_ignore_sigpipe() == -1) ||
((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1))
return -1;
if (((retval =
connect(sock, (struct sockaddr *)&server, sizeof(server))) == -1) &&
((errno == EINTR) || (errno == EALREADY))) {
FD_ZERO(&sockset);
FD_SET(sock, &sockset);
while ( ((retval = select(sock+1, NULL, &sockset, NULL, NULL)) == -1) &&
(errno == EINTR) ) {
FD_ZERO(&sockset);
FD_SET(sock, &sockset);
}
}
if (retval == -1) {
error = errno;
while ((close(sock) == -1) && (errno == EINTR));
errno = error;
return -1;
}
return sock;
}
g++ main.cpp -luici
rgonzale@darkstar:~1060 g++ main.cpp -luici
main.cpp: In function ‘int login()’:
main.cpp:17: warning: deprecated conversion from string constant to ‘char*’
/tmp/cchB0XrG.o: In function `login()':
main.cpp:(.text+0x24): undefined reference to `u_connect(unsigned short, char*)'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libuici.so: undefined reference to `addr2name'
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/libuici.so: undefined reference to `name2addr'
collect2: ld returned 1 exit status
The header files that I include have the prototypes for u_connect, addr2name, and name2addr.
I am using CentOS 6.8 on a 64 bit server. I understand that I am using a C shared library and headers with a C++ program. I heard you can do this so that is why I am trying. I don't want to use boost. Thank you.
Also, I could put the header files(uici.h and uiciname.h) into /usr/include then change them to "uici.h" "uiciname.h" to <uici.h> and <uiciname.h> correct?
Where is the actual code for the addr2name and name2addr functions? It should be in your library but I can't see it there. Your error comes from ld and not from gcc, so it is the code for these functions that is not being found; the definitions in the headers have been read successfully.
which I compiled into a shared lib and put into /usr/lib64
Code:
rgonzale@darkstar:~1088 g++ main.cpp -luici -luiciname
main.cpp: In function ‘int login()’:
main.cpp:17: warning: deprecated conversion from string constant to ‘char*’
/tmp/cc2Iv0nF.o: In function `login()':
main.cpp:(.text+0x24): undefined reference to `u_connect(unsigned short, char*)'
collect2: ld returned 1 exit status
Great that worked thank you NevemTeve. What does the extern "C" do exactly? I know extern names it a global variable but what is happening behind the scenes. How did this satisfy the linker?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.