como compilar este codigo??

gerard
01 de Enero del 2005
Al compilar el codigo de aquí abajo con g++ me da error al linkar. Alguien me puede decir porque? Es un codigo copiado que a priori tendría que fucionar. Lo que pasa es que he cojido los trozitos de un documento y quizas el orden de las clases no este bien.


#include <signal.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>

class Event_Handler
{
public:
// Hook method for the signal hook method.
virtual int handle_signal (int signum) = 0;

// ... other hook methods for other types of
// events such as timers, I/O, and
// synchronization objects.
};


class Signal_Handler
{
public:
// Entry point.
static Signal_Handler *instance (void);

// Register an event handler <eh> for <signum>
// and return a pointer to any existing <Event_Handler>
// that was previously registered to handle <signum>.
Event_Handler *register_handler (int signum,Event_Handler *eh);

// Remove the <Event_Handler> for <signum>
// by setting the slot in the <signal_handlers_>
// table to NULL.
int remove_handler (int signum);

private:
// Ensure we're a Singleton.
Signal_Handler (void);

// Singleton pointer.
static Signal_Handler *instance_;

// Entry point adapter installed into <sigaction>
// (must be a static method or a stand-alone
// extern "C" function).
static void dispatcher (int signum);

// Table of pointers to concrete <Event_Handler>s
// registered by applications. NSIG is the number of
// signals defined in </usr/include/sys/signal.h>.
static Event_Handler *signal_handlers_[NSIG];
};


Event_Handler * Signal_Handler::register_handler (int signum, Event_Handler *eh){
// Copy the <old_eh> from the <signum> slot in
// the <signal_handlers_> table.
Event_Handler *old_eh = Signal_Handler::signal_handlers_[signum];

// Store <eh> into the <signum> slot in the
// <signal_handlers_> table.
Signal_Handler::signal_handlers_[signum] = eh;

// Register the <dispatcher> to handle this
// <signum>.
struct sigaction sa;
sa.sa_handler = Signal_Handler::dispatcher;
sigemptyset (&sa.sa_mask);
sa.sa_flags = 0;
sigaction (signum, &sa, 0);

return old_eh;
}

void Signal_Handler::dispatcher (int signum){
// Perform a sanity check...
if (Signal_Handler::signal_handlers_[signum] != 0)
// Dispatch the handler's hook method.
Signal_Handler::signal_handlers_
[signum]->handle_signal (signum);
}

class SIGINT_Handler : public Event_Handler{
public:
SIGINT_Handler (void)
: graceful_quit_ (0) {}

// Hook method.
virtual int handle_signal (int signum){
assert (signum == SIGINT);
this->graceful_quit_ = 1;
}

// Accessor.
sig_atomic_t graceful_quit (void)
{ return this->graceful_quit_; }

private:
sig_atomic_t graceful_quit_;
};

class SIGQUIT_Handler : public Event_Handler{
public:
SIGQUIT_Handler (void)
: abortive_quit_ (0) {}

// Hook method.
virtual int handle_signal (int signum){
assert (signum == SIGQUIT);
this->abortive_quit_ = 1;
}

// Accessor.
sig_atomic_t abortive_quit (void)
{ return this->abortive_quit_; }

private:
sig_atomic_t abortive_quit_;
};

int main (void){
SIGINT_Handler sigint_handler;
SIGQUIT_Handler sigquit_handler;

// Register the handler for SIGINT.
Signal_Handler::instance ()->register_handler (SIGINT, &sigint_handler);

// Register the handler for SIGQUIT.
Signal_Handler::instance ()->register_handler (SIGQUIT, &sigquit_handler);

// Run the main event loop.
while (sigint_handler.graceful_quit () == 0 && sigquit_handler.abortive_quit () == 0)
printf("treballa");

if (sigquit_handler.abortive_quit () == 1)
_exit (1);
else /* if sigint_handler.graceful_quit () */ {
printf("neteja");
return 1;
}
}

Alejandro_
01 de Enero del 2005
En principio, deberías cambiar los nombres de los archivos cabecera, que son obsoletos, y el g++ no los admite:

#include <cstdio> // por <stdio.h>
#include <cstdlib> // por <stdlib.h>

Alejandro


chuidiang
01 de Enero del 2005
Al compilar, además de poner los include de los .h correspondientes, debes poner las librerías extras que utilices. Para identificar la libreria extra no estaría de más que pusieras el error que está dando.

Por ejemplo, si usas sockets, el prototipo de la funcion socket() esta en include <sys/socket.h> pero al compilar dará error de enlazado. El código de la funcion socket() está en la libreria libsocket.a del sistema y debes incluirla en la linea de compilado con -lsocket asi

g++ principal.cc -lsocket -o principal

En tu caso puede pasar algo parecido (con otra libreria), por ello, insisto, si no eres capaz de identificar la libreria, deberías poner el error.

Se bueno.

gerard
01 de Enero del 2005
Hola,
muchas gracias por vuestras buenas intenciones pero de momento no lo consigo. Tengo que decir que todo lo que veis es todo lo que tengo y lo tengo metido en un .cpp. El error que me da es el siguiente:

galco@linux:~/xarxes> g++ senyaloriginal.cpp
/tmp/cceB25oJ.o(.text+0xf): En la función `Signal_Handler::register_handler(int, Event_Handler*)':
: undefined reference to `Signal_Handler::signal_handlers_'
/tmp/cceB25oJ.o(.text+0x1f): En la función `Signal_Handler::register_handler(int, Event_Handler*)':
: undefined reference to `Signal_Handler::signal_handlers_'
/tmp/cceB25oJ.o(.text+0x72): En la función `Signal_Handler::dispatcher(int)':
: undefined reference to `Signal_Handler::signal_handlers_'
/tmp/cceB25oJ.o(.text+0x82): En la función `Signal_Handler::dispatcher(int)':
: undefined reference to `Signal_Handler::signal_handlers_'
/tmp/cceB25oJ.o(.text+0x91): En la función `Signal_Handler::dispatcher(int)':
: undefined reference to `Signal_Handler::signal_handlers_'
/tmp/cceB25oJ.o(.text+0xd9): En la función `main':
: undefined reference to `Signal_Handler::instance()'
/tmp/cceB25oJ.o(.text+0xf6): En la función `main':
: undefined reference to `Signal_Handler::instance()'
collect2: ld returned 1 exit status

chuidiang
01 de Enero del 2005
Bueno, no se si te arregla todo ni si ya lo has hecho (en el codigo, sin sangrar como se ve aqui, me cuesta buscarlo).
Los atributos estaticos debes declararlos tambien fuera del class, al igual que donde pones el codigo de los metodos

class A ...
{
static int a;
};

int A::a; // esto es lo que te falta con el signal_handlers_

En cuanto al instance(), parece que se te ha olvidado declararlo...

Se bueno.

gerard
01 de Enero del 2005
Muchas gracias por tu ayuda chuidiang al fin he podido compilar el código. Como tu decías faltaba declarar fuera de la clase el signal_handlers_ y definir los metodos que no lo estaban.

Por cierto, no te preocupes que seré bueno ;-)