Jason Priest
Jason Priest

Reputation: 11

C++ Library Troubles with GCC

I'm brand new to C++ but I have a lot of general experience with programming, so I'm familiar with most low level concepts.

Anyway, I thought I'd try writing an IRC client, since IRC appears to have a relatively simple TCP protocol. (It's so easy, you can access and use a server via Telnet, it's unpractical, but doable)

So I googled "C++ socket library" and came across dlib, a general purpose library that includes some socket support.

I look into the documents, found an example that should echo anything it receives, and tried to compile it. But, I got tons of errors about "undefined references" to functions.

I don't really know what to do now. Can anyone give me some advice ?

I'm building this in Code::Blocks v10.05 and GCC 4.4.1 (I'd use 4.6.1, but I've yet to figure out how to get Code::Blocks to compile that way)

Here's the exact example:

// The contents of this file are in the public domain. See LICENSE_FOR_EXAMPLE_PROGRAMS.txt
/*

    This is an example illustrating the use of the sockets and
    server components from the dlib C++ Library.

    This is a simple echo server.  It listens on port 1234 for incoming
    connections and just echos back any data it receives.

*/




#include "dlib/sockets.h"
#include "dlib/server.h"
#include "dlib/ref.h" // for ref()
#include <iostream>

using namespace dlib;
using namespace std;



class serv : public server::kernel_1a_c
{

    void on_connect  (
        connection& con
    )
    {
        char ch;
        while (con.read(&ch,1) > 0)
        {
            // we are just reading one char at a time and writing it back
            // to the connection.  If there is some problem writing the char
            // then we quit the loop.
            if (con.write(&ch,1) != 1)
                break;
        }
    }

};


void thread(serv& our_server)
{
    try
    {
        // Start the server.  start() blocks until the server is shutdown
        // by a call to clear()
        our_server.start();
    }
    catch (socket_error& e)
    {
        cout << "Socket error while starting server: " << e.what() << endl;
    }
    catch (exception& e)
    {
        cout << "Error while starting server: " << e.what() << endl;
    }
}


int main()
{
    try
    {
        serv our_server;

        // set up the server object we have made
        our_server.set_listening_port(1234);
        our_server.set_max_connections(1000);

        // create a thread that will start the server.   The ref() here allows us to pass
        // our_server into the threaded function by reference.
        thread_function t(thread, dlib::ref(our_server));

        cout << "Press enter to end this program" << endl;
        cin.get();
        // this will cause the server to shut down
        our_server.clear();
    }
    catch (exception& e)
    {
        cout << e.what() << endl;
    }
    catch (...)
    {
        cout << "Some error occurred" << endl;
    }
}

And then here is the output:

-------------- Build: Release in test ---------------

Compiling: main.cpp
Linking console executable: bin\test.exe
obj\main.o:main.cpp:(.text+0xe): undefined reference to `dlib::logger::~logger()'
obj\main.o:main.cpp:(.text+0x1d3): undefined reference to `dlib::logger::logger(char const*)'
obj\main.o:main.cpp:(.text+0x3cf): undefined reference to `dlib::threaded_object::threaded_object()'
obj\main.o:main.cpp:(.text+0x44a): undefined reference to `dlib::threaded_object::start()'
obj\main.o:main.cpp:(.text+0x4ef): undefined reference to `dlib::threaded_object::wait() const'
obj\main.o:main.cpp:(.text+0x523): undefined reference to `dlib::threaded_object::~threaded_object()'
obj\main.o:main.cpp:(.text+0x5e8): undefined reference to `dlib::threaded_object::~threaded_object()'
obj\main.o:main.cpp:(.text+0x701): undefined reference to `dlib::threaded_object::~threaded_object()'
obj\main.o:main.cpp:(.text$_ZN4serv10on_connectERN4dlib10connectionE[serv::on_connect(dlib::connection&)]+0x20): undefined reference to `dlib::connection::read(char*, long)'
obj\main.o:main.cpp:(.text$_ZN4serv10on_connectERN4dlib10connectionE[serv::on_connect(dlib::connection&)]+0x38): undefined reference to `dlib::connection::write(char const*, long)'
obj\main.o:main.cpp:(.text$_ZN4dlib15thread_functionD0Ev[dlib::thread_function::~thread_function()]+0x43): undefined reference to `dlib::threaded_object::wait() const'
obj\main.o:main.cpp:(.text$_ZN4dlib15thread_functionD0Ev[dlib::thread_function::~thread_function()]+0x70): undefined reference to `dlib::threaded_object::~threaded_object()'
obj\main.o:main.cpp:(.text$_ZN4dlib15thread_functionD0Ev[dlib::thread_function::~thread_function()]+0xbe): undefined reference to `dlib::threaded_object::~threaded_object()'
obj\main.o:main.cpp:(.text$_ZN4dlib15thread_functionD1Ev[dlib::thread_function::~thread_function()]+0x43): undefined reference to `dlib::threaded_object::wait() const'
obj\main.o:main.cpp:(.text$_ZN4dlib15thread_functionD1Ev[dlib::thread_function::~thread_function()]+0x70): undefined reference to `dlib::threaded_object::~threaded_object()'
obj\main.o:main.cpp:(.text$_ZN4dlib15thread_functionD1Ev[dlib::thread_function::~thread_function()]+0xb3): undefined reference to `dlib::threaded_object::~threaded_object()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5clearEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::clear()]+0x10e): undefined reference to `dlib::connection::shutdown()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE18service_connectionEPv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::service_connection(void*)]+0x9e): undefined reference to `dlib::close_gracefully(dlib::connection*, unsigned long)'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE18service_connectionEPv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::service_connection(void*)]+0x352): undefined reference to `dlib::logger::logger_stream::print_end_of_line()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE18service_connectionEPv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::service_connection(void*)]+0x3c5): undefined reference to `dlib::logger::logger_stream::print_header_and_stuff()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE18service_connectionEPv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::service_connection(void*)]+0x3f3): undefined reference to `dlib::logger::logger_stream::print_end_of_line()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0x58): undefined reference to `dlib::create_listener(dlib::listener*&, unsigned short, std::string const&)'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0x11d): undefined reference to `dlib::listener::accept(dlib::connection*&, unsigned long)'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0x244): undefined reference to `dlib::threads_kernel_shared::thread_pool()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0x25b): undefined reference to `dlib::threads_kernel_shared::threader::create_new_thread(void (*)(void*), void*)'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0x4a3): undefined reference to `dlib::listener::~listener()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0x648): undefined reference to `dlib::connection::~connection()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0x949): undefined reference to `dlib::listener::~listener()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0x9bd): undefined reference to `dlib::connection::~connection()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0xdd0): undefined reference to `dlib::listener::~listener()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0xdf4): undefined reference to `dlib::connection::~connection()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0xf7c): undefined reference to `dlib::listener::~listener()'
obj\main.o:main.cpp:(.text$_ZN4dlib15server_kernel_1INS_12set_kernel_1IPNS_10connectionENS_27binary_search_tree_kernel_1IS3_cNS_33memory_manager_stateless_kernel_1IcEESt4lessIS3_EEES6_EEE5startEv[dlib::server_kernel_1<dlib::set_kernel_1<dlib::connection*, dlib::binary_search_tree_kernel_1<dlib::connection*, char, dlib::memory_manager_stateless_kernel_1<char>, std::less<dlib::connection*> >, dlib::memory_manager_stateless_kernel_1<char> > >::start()]+0xfa0): undefined reference to `dlib::connection::~connection()'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 5 seconds)
33 errors, 0 warnings

Upvotes: 1

Views: 3361

Answers (4)

Davis King
Davis King

Reputation: 4791

Did you read dlib's How to compile page? It sounds like you forgot to add dlib/all/source.cpp to your project. Adding that should make those linker errors go away. Also, since you are using Code::Blocks, you will need to tell it to link with these windows libraries: gdi32, comctl32, user32, ws2_32, and imm32.

It's also worth pointing out that there is a free version of Visual Studio 2010 which you can use to compile these C++ programs. If you are compiling on windows I would definitely recommend using this compiler instead of Code::Blocks.

On my system (Windows XP in a virtual box VM with 3.5GB of RAM) Code::Blocks compiles without issue using the above method. However, if it refuses to compile dlib/all/source.cpp you should just add the files listed in dlib/all/source.cpp to your project individually instead. The only reason source.cpp is included is for convenience and it really isn't needed.

Upvotes: 1

sashang
sashang

Reputation: 12194

It looks like you're missing the option that tells gcc to link with the dlib library. I don't know what the specific setting thing to do for Code::Blocks is but in general with gcc you would need to use the -l option like this:

gcc <other compiler options> -ldlib

update

Ok I had a better look into this and it looks like dlib doesn't actually build a library for you. The common way that external libraries packages work is by providing a makefile that build you the *.a or *.so files that you need to link with. However dlib doesn't provide this and requires you to add its special source.cpp to your build settings. Again I don't know how to do this in codeblocks but the following worked for me when compiling and linking that socket example:

g++ -o dlib_socket -I ../dlib-17.42/ -lpthread -lX11 dlib_socket.cpp ../dlib-17.42/dlib/all/source.cpp

In the example above I extracted dlib into the parent directory (hence the ../dlib-17.42/dlib)

Upvotes: 4

Nor
Nor

Reputation: 115

First and formost http://beej.us/guide/bgnet/ tells you everything you need to know about socket programming. Jumping into a libary before you understand the basics is counter productive with sockets. Most socket libarys are simple wrapers which handle the data structs for you.

here is a class i wrote years ago for windows.

#pragma once
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
class cMySocket {
public:
    cMySocket(void);
    ~cMySocket(void);

    int startup_server(int type, unsigned __int16 port, const char* ip );
    void shutdown_server();
    operator SOCKET();
    cMySocket & operator=(const SOCKET &s);

    bool           running;
    SOCKET         m_socket;
    sockaddr_in    service;
    sockaddr_in    client_addr;
};
cMySocket::cMySocket(void){
    m_socket = SOCKET_ERROR;
    running = false;
}

cMySocket::~cMySocket(void){
    if( m_socket != SOCKET_ERROR )
        closesocket(m_socket);
}

int cMySocket::startup_server(int type, unsigned __int16 port, const char* ip ){
    unsigned long iMode = 1;

    m_socket = socket(AF_INET, type, 0);
    if (m_socket == INVALID_SOCKET){
        throw "Error at socket()\n";
    }

    if( ioctlsocket(m_socket, FIONBIO, &iMode) == SOCKET_ERROR){
        closesocket(m_socket);
        throw "Error at ioctlsocket()\n";
    }

    memset( &service, 0, sizeof( service ));
    service.sin_family = AF_INET;
    service.sin_addr.s_addr = inet_addr(ip);
    service.sin_port = htons(port);

    if( bind(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR ){
        closesocket(m_socket);
        throw "Error at bind()\n";
    }
    iMode = 1;
    if ( ioctlsocket( m_socket, FIONBIO, &iMode ) )
    {
        closesocket(m_socket);
        throw "Error at iostlcosket()\n";
    }
    if( type == SOCK_STREAM ){
        if( listen( m_socket, 10) == SOCKET_ERROR ){
            closesocket(m_socket);
            throw "Error at listen()\n";
        }
    }
    running = true;
    return 1;
}

void cMySocket::shutdown_server(){
    closesocket( m_socket );
    m_socket = SOCKET_ERROR;
    running = false;
}

cMySocket::operator SOCKET () { 
    return m_socket; 
}

cMySocket & cMySocket::operator=(const SOCKET &s){  
    m_socket = s;
    return *this;
}

You still have to use connect, accept, send, recv functions on your on, as well as error checking. Unless your using some kind of implimted protocal provided by your libary, I suggest coding the socket implimentation yourself.

Upvotes: 0

Mikhail
Mikhail

Reputation: 8028

You would be better off not using C::B. Try NetBeans because it will produce make files.

Right click on the project and go to build options. There you will find linker. Add the library from there.

http://www.learncpp.com/cpp-tutorial/a3-using-libraries-with-codeblocks/

Upvotes: -1

Related Questions