• Domingo 15 de Diciembre de 2024, 05:58

Autor Tema:  Problema Con _beginthreadex En Una Clase  (Leído 2832 veces)

captaindanieo

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Problema Con _beginthreadex En Una Clase
« en: Martes 6 de Noviembre de 2007, 08:05 »
0
Hola.

Es mi primer mensaje en el foro. Aprovecho para saludar y daros a todos las gracias por vuestra ayuda.

Soy un programador mas o menos novato, y no tengo mucha o ninguna idea de muchas, cosas, y bueno.

Vereis. Para la implementación del programa que estoy haciendo, he tenido que usar comunicación por sockets, para que se comuniquen dos entidades de mi programa.

Y para ello he usado una clase socket implementada, que contaba con ejemplos de servidor y de cliente.

El problema está en que estoy usando dicha clase socket, en una clase mia que me he creado.

El código de la clase socket, para un servidor, tal y como estaba definido por el autor de la clase es el siguiente (no es el que yo tengo en mi programa, que lo he puesto mas abajo):


Código: Text
  1. unsigned __stdcall Answer(void* a) {
  2.   Socket* s = (Socket*) a;
  3.  
  4.   while (1) {
  5.     std::string r = s->ReceiveLine();
  6.     if (r.empty()) break;
  7.     s->SendLine(r);
  8.   }
  9.  
  10.   delete s;
  11.  
  12.   return 0;
  13. }
  14.  
  15.  
  16. int main(int argc, char* argv[]) {
  17.   SocketServer in(2000,5);
  18.  
  19.   while (1) {
  20.     Socket* s=in.Accept();
  21.  
  22.     unsigned ret;
  23.     _beginthreadex(0,0,Answer,(void*) s,0,&ret);
  24.   }
  25.   
  26.   return 0;
  27. }
  28.  
  29.  




En mi programa, mi problema está en que yo estoy haciendo uso de dicha clase socket, y de actuar como servidor, dentro de una clase que me he creado. Y el problema que tengo es que, tras recibir datos por el socket, yo quiero comprobar si son un tipo de datos u otros, y uso variables globales pertenecientes a mi clase.


Para trabajar en mi clase tendre que declarar la función main como Nombremiclase::Server(int arg...).

Y para ver las variables globales desde la stdcall, supongo que tendré que ponerla en mi clase también...

No se, llevo varios dias intentandolo y estoy hundido, no hay manera. A ver si alguien supiese.



Os dejo el codigo que tengo implementado en mi clase, y el error que obtengo, que es :

In member function 'void L2cap::Server (int,char**)'
argument of type 'unsigned int (L2cap:: )(void*) does not match 'unsigned int (*)(void*)')
Buil error (L2cap.o) Error 1.


Código: Text
  1.  
  2. unsigned __stdcall L2cap::Answer(void* a)
  3. {
  4.   L2capChannel canal;
  5.   Socket* s = (Socket*) a;
  6.     unsigned int longitud, leidos, tipo, pos, NumBytes,opt;
  7.       unsigned int* datain = NULL;
  8.     int size;
  9.  
  10.  
  11.  
  12.   while (1) // escuchando
  13.   {
  14.     std::string r = s->ReceiveBytes();
  15.     
  16.     size = r.length();
  17.     L2cap::string_to_bytearray(r,datain,size);
  18.     
  19.  
  20.     Write(datain,size);
  21.  
  22.     longitud = size-4; // se trata del campo length, mientras q size es toda
  23.  
  24.  
  25.    tipo = Leertipotrama (datain);
  26.  
  27.     
  28.     if (r =="exit")
  29.     {
  30. //          escuchando = false;
  31. //          cout<<"Escuchando se ha puesto a false"<<endl;
  32.     }
  33.     else if ((r.length())>0)
  34.     {
  35.        cout <<"Recibida una string de longitud "<<r.length()<<endl<<"y contenido: "<<r<<endl<<endl;                
  36.        canal.EntradaDatos(r);
  37.     }
  38.  
  39. //    s->SendBytes(r);
  40.   }
  41.   delete s;
  42.  
  43.   return 0;
  44. }
  45.  
  46.  
  47.  
  48. void L2cap::Server(int argc, char* argv[]) // Modo Servidor
  49. {
  50.   SocketServer in(3000,5);
  51.  
  52.   while (escuchando)
  53.   {
  54.     Socket* s=in.Accept();
  55.  
  56.     unsigned ret;
  57.     _beginthreadex(0,0,L2cap::Answer,(void*) s,0,&ret);
  58.   }
  59. }
  60.  
  61.  


Ojalá podais ayudarme, muchísimas gracias de antemano.

Un saludo.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #1 en: Martes 6 de Noviembre de 2007, 09:00 »
0
¿Dentro del mismo programa (en la misma instancia) usas sockets?

Para que el _beginthreadex compile hace:
_beginthreadex(0,0,L2cap::Answer,(void*) s,0,&ret);

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

captaindanieo

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #2 en: Martes 6 de Noviembre de 2007, 15:27 »
0
Hola.

Si, efectivamente. Dentro de mi clase, uso la clase socket para establecer una conexion con otra clase igual que la mia.

La declaración de beginthreadex que tengo puesta en mi código es esa misma, y obtengo el error siguiente:

In member function 'void L2cap::Server (int,char**)'
argument of type 'unsigned int (L2cap:: )(void*) does not match 'unsigned int (*)(void*)')
Buil error (L2cap.o) Error 1.


Parece que al estar dentro de mi clase L2cap, obtiene un error de parámetros o algo. Ahi es donde tengo el problema.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #3 en: Martes 6 de Noviembre de 2007, 15:46 »
0
Cita de: "captaindanieo"
Si, efectivamente.

Bueno, no tiene ningun sentido recurrir a una libreria de red para eso ...

Cita de: "captaindanieo"
Parece que al estar dentro de mi clase L2cap, obtiene un error de parámetros o algo. Ahi es donde tengo el problema.

Si declaraste la funcion como static asi te deberia funcionar ...

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

captaindanieo

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #4 en: Miércoles 7 de Noviembre de 2007, 08:48 »
0
¿Que significa declarar esa función como static Eternal Idol? Es que soy totalmente novato en la programación y me pierdo. :(

El código que yo tengo en mi programa, y que da problemas, es el de abajo del primer post.

Las declaraciones las tengo tal y como están ahí, pero obtengo el error de tipos ese que he resaltado en negrita.

¿Puede ser que beginthreadex no pueda usarse dentro de una clase?

Si le quito el que esté dentro de mi clase, es decir, si la función Answer no la defino como L2cap::Answer, y en los parámetros elimino también el L2cap:: (en beginthreadex, para Answer), el código funciona. Pero si no incluyese referencia a ningún objeto de mi clase L2cap. En cuanto hago referencia a una variable por ejemplo, obtengo el error de que no está definida.

Es que creo que no me había explicado bien del todo.

Un saludo y muchísimas gracias de nuevo.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #5 en: Miércoles 7 de Noviembre de 2007, 09:53 »
0
Cita de: "captaindanieo"
¿Que significa declarar esa función como static Eternal Idol? Es que soy totalmente novato en la programación y me pierdo. :(

Que sea una funcion independiente de una instancia de la clase.

Cita de: "captaindanieo"
¿Puede ser que beginthreadex no pueda usarse dentro de una clase?

Exacto.

Código: Text
  1.  
  2. class L2cap
  3. {
  4.   public:
  5.     static unsigned __stdcall Answer(void* a);
  6. };
  7.  
  8.  

Mientras no uses ningun variable miembro de la clase no hay problema, sino tenes que pasarle un puntero a la instancia del objeto ya que al ser una funcion estatica no tiene puntero this (no pertenece a ninguna instancia de la clase). Al ser un solo parametro el que se le puede pasar a un hilo normalmente se usa una estructura con varios campos, en este caso por ejemplo el this y el a. Sino creas otro miembro en la clase L2cap y antes de crear el hilo le asignas a ese campo el valor de a y solo tenes que pasar this para trabajar.

Pero vuelvo al principio: no es necesario usar sockets - y no tiene logica - dentro un programa sino se necesita comunicaciones por red.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

captaindanieo

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #6 en: Miércoles 7 de Noviembre de 2007, 21:38 »
0
Muchas gracias de nuevo. La comunicación por sockets la requiero porque me es necesario para simular el comportamiento entre dos instancias de mi programa, que se estén ejecutando, ya sea en la misma máquina o en máquinas distintas.

No he entendido muy bien la solución de crearme otro miembro en la clase l2cap, ¿a que se refiere? :(

De todas formas muchas gracias por tus respuestas Eternal Idol.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #7 en: Miércoles 7 de Noviembre de 2007, 21:47 »
0
Cita de: "captaindanieo"
Muchas gracias de nuevo. La comunicación por sockets la requiero porque me es necesario para simular el comportamiento entre dos instancias de mi programa, que se estén ejecutando, ya sea en la misma máquina o en máquinas distintas.

Bueno, eso fue lo primero que te pregunte, si eran la misma instancia ... me dijiste que si pero en realidad la respuesta era no  ;)

Cita de: "captaindanieo"
No he entendido muy bien la solución de crearme otro miembro en la clase l2cap, ¿a que se refiere? :(

NO es otro miembro, es el mismo pero estatico, declaralo asi y tu programa compilara.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

captaindanieo

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #8 en: Jueves 8 de Noviembre de 2007, 00:31 »
0
Si pongo Answer como estátito cobtengo el error siguiente:

invalid use of member L2cap::escuchando in static member function  :(


He intentado aislar mi código, de manera que se pueda probar a compilar el código aquí escrito. Ya que si pongo solo partes del código no podemos probar a compilar quizás y no damos con la solución quizás.

El código completo de la clase l2cap, tanto el h como el cpp es el siguiente:

l2cap.h

Código: Text
  1. #include <Socket.h>
  2. #include <string>
  3. #include <sstream>
  4. #include <iostream>
  5. #include <cstdlib>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8.  
  9.  
  10. class L2cap
  11. {
  12.  
  13.  public:
  14.         
  15.      L2cap ();
  16.      void Conecta(); // Modo Cliente        
  17.      void Server(int argc, char* argv[]); // Modo Servidor
  18.  
  19.  
  20.  private:    
  21.                        // VARIABLES GLOBALES
  22.      bool escuchando;
  23.  
  24.                          //     FUNCIONES
  25.      static unsigned __stdcall L2cap::Answer(void* a);
  26.     
  27. };
  28.  
  29.  
  30.  

L2cap.cpp

Código: Text
  1. #include <L2cap.h>
  2. #include <Socket.h>
  3. #include <process.h>
  4. #include <string>
  5. #include <sstream>
  6. #include <iostream>
  7. #include <cstdlib>
  8. #include <stdio.h>
  9.  
  10. using namespace std;
  11.  
  12.  
  13.  
  14. L2cap::L2cap ()  // Constructor
  15. {
  16.    escuchando = true;
  17. }
  18.  
  19.  
  20.  
  21. unsigned __stdcall L2cap::Answer(void* a)
  22. {
  23.   Socket* s = (Socket*) a;
  24.   int size;
  25.  
  26.   while (1) // escuchando
  27.   {
  28.     std::string r = s->ReceiveBytes();  
  29.     size = r.length();
  30.     if (size>0)
  31.     {  
  32.       if (escuchando);  // <- aqui obtengo el error. no la ve
  33.     }
  34.   }
  35.   delete s;
  36.   return 0;
  37. }
  38.  
  39.  
  40. void L2cap::Server(int argc, char* argv[]) // Modo Servidor
  41. {
  42.   SocketServer in(3000,5);
  43.  
  44.   while (escuchando)
  45.   {
  46.     Socket* s=in.Accept();
  47.     unsigned ret;
  48.     _beginthreadex(0,0,Answer,(void*) s,0,&ret);
  49.   }
  50. }
  51.  
  52.  
  53. void L2cap::Conecta()
  54. {
  55.     std::string cadena;
  56.  
  57.   try
  58.   {
  59.     SocketClient s("pc.", 3000); //Ya esta abierto, no tengo que hacerlo de nuevo.??
  60.     cadena = "1600010002050400010040000A06020001000607040043004000";
  61.     s.SendBytes(cadena);
  62.   }
  63.   catch (const char* s)
  64.   {
  65.     cerr << s << endl;
  66.   }
  67.   catch (std::string s)
  68.   {
  69.     cerr << s << endl;
  70.   }
  71.   catch (...)
  72.   {
  73.     cerr << "unhandled exception\n";
  74.   }
  75. }
  76.  
  77.  


programa principal: principal.cpp

Código: Text
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <L2cap.h>
  4.  
  5.  
  6. using namespace std;
  7.  
  8. int main()
  9. {
  10.     int opcion;
  11.     L2cap micapa;
  12.     
  13.     cout <<endl<<"                *-----------------------------------------*";
  14.     cout <<endl<<"                |  1.- Modo Servidor................. (1) |";
  15.     cout <<endl<<"                |  2.- Modo Cliente manda msg........ (2) |";
  16.     cout <<endl<<"                *-----------------------------------------*"<<endl<<endl;
  17.     cout <<endl<<"                  >  Elija una Opcion.......... ";
  18.     scanf("%d",&opcion);
  19.  
  20.   //Lee Menu y llama funciones
  21.   switch(opcion)
  22.     {
  23.          case 1:
  24.              {
  25.               micapa.Server(1,0);
  26.               break;
  27.              }
  28.          case 2:
  29.              {
  30.               micapa.Conecta();
  31.               break;
  32.              }  
  33.     }
  34.   return 0;
  35. }  
  36.  
  37.  


Y bueno, los archivos de la clase socket, son:

el socket.cpp

Código: Text
  1. #include <SOCKET.h>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6.  
  7. int Socket::nofSockets_= 0;
  8.  
  9.  
  10. void Socket::Start()
  11. {
  12.   if (!nofSockets_)
  13.   {
  14.     WSADATA info;
  15.     if (WSAStartup(MAKEWORD(2,0), &info))
  16.     {
  17.       throw "Could not start WSA";
  18.     }
  19.   }
  20.   ++nofSockets_;
  21. }
  22.  
  23.  
  24. void Socket::End()
  25. {
  26.   WSACleanup();
  27. }
  28.  
  29.  
  30. Socket::Socket() : s_(0)
  31. {
  32.   Start();
  33.   // UDP: use SOCK_DGRAM instead of SOCK_STREAM
  34.   s_ = socket(AF_INET,SOCK_STREAM,0);
  35.  
  36.   if (s_ == INVALID_SOCKET)
  37.   {
  38.     throw "INVALID_SOCKET";
  39.   }
  40.  
  41.   refCounter_ = new int(1);
  42. }
  43.  
  44.  
  45. Socket::Socket(SOCKET s) : s_(s)
  46. {
  47.   Start();
  48.   refCounter_ = new int(1);
  49. };
  50.  
  51.  
  52. Socket::~Socket()
  53. {
  54.   if (! --(*refCounter_))
  55.   {
  56.     Close();
  57.     delete refCounter_;
  58.   }
  59.  
  60.   --nofSockets_;
  61.   if (!nofSockets_) End();
  62. }
  63.  
  64.  
  65. Socket::Socket(const Socket& o)
  66. {
  67.   refCounter_=o.refCounter_;
  68.   (*refCounter_)++;
  69.   s_         =o.s_;
  70.  
  71.   nofSockets_++;
  72. }
  73.  
  74.  
  75. Socket& Socket::operator=(Socket& o)
  76. {
  77.   (*o.refCounter_)++;
  78.  
  79.   refCounter_=o.refCounter_;
  80.   s_         =o.s_;
  81.  
  82.   nofSockets_++;
  83.  
  84.   return *this;
  85. }
  86.  
  87.  
  88. void Socket::Close()
  89. {
  90.   closesocket(s_);
  91. }
  92.  
  93.  
  94. std::string Socket::ReceiveBytes()
  95. {
  96.   std::string ret;
  97.   char buf[1024];
  98.  
  99.   while (1) {
  100.     u_long arg = 0;
  101.     if (ioctlsocket(s_, FIONREAD, &arg) != 0)
  102.     {
  103.       break;
  104.     }
  105.  
  106.     if (arg == 0)
  107.     {
  108.       break;
  109.     }
  110.     
  111.     if (arg > 1024)
  112.     {
  113.             arg = 1024;
  114.     }
  115.  
  116.     int rv = recv (s_, buf, arg, 0);
  117.  
  118.     if (rv <= 0)
  119.     {
  120.            break;
  121.     }
  122.  
  123.     std::string t;
  124.  
  125.     t.assign (buf, rv);
  126.     ret += t;
  127.   }
  128.  
  129.   return ret;
  130. }
  131.  
  132.  
  133. std::string Socket::ReceiveLine()
  134. {
  135.   std::string ret;
  136.   while (1)
  137.   {
  138.     char r;
  139.  
  140.     switch(recv(s_, &r, 1, 0))
  141.     {
  142.       case 0: // not connected anymore;
  143.               // ... but last line sent
  144.               // might not end in \n,
  145.               // so return ret anyway.
  146.         return ret;
  147.  
  148.       case -1:
  149.         return "";
  150. //      if (errno == EAGAIN) {
  151. //        return ret;
  152. //      } else {
  153. //      // not connected anymore
  154. //      return "";
  155. //      }
  156.     }
  157.  
  158.     ret += r;
  159.     if (r == '\n')  return ret;
  160.   }
  161. }
  162.  
  163.  
  164. void Socket::SendLine(std::string s)
  165. {
  166.   s += '\n';
  167.   send(s_,s.c_str(),s.length(),0);
  168. }
  169.  
  170.  
  171. void Socket::SendBytes(const std::string& s)
  172. {
  173.   send(s_,s.c_str(),s.length(),0);
  174. }
  175.  
  176.  
  177. SocketServer::SocketServer(int port, int connections, TypeSocket type)
  178. {
  179.   sockaddr_in sa;
  180.  
  181.   memset(&sa, 0, sizeof(sa));
  182.  
  183.   sa.sin_family = PF_INET;            
  184.   sa.sin_port = htons(port);          
  185.   s_ = socket(AF_INET, SOCK_STREAM, 0);
  186.   if (s_ == INVALID_SOCKET)
  187.   {
  188.     throw "INVALID_SOCKET";
  189.   }
  190.  
  191.   if(type==NonBlockingSocket)
  192.   {
  193.     u_long arg = 1;
  194.     ioctlsocket(s_, FIONBIO, &arg);
  195.   }
  196.  
  197.   /* bind the socket to the internet address */
  198.   if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR)
  199.   {
  200.     closesocket(s_);
  201.     throw "INVALID_SOCKET";
  202.   }
  203.   
  204.   listen(s_, connections);                              
  205. }
  206.  
  207.  
  208. Socket* SocketServer::Accept()
  209. {
  210.   SOCKET new_sock = accept(s_, 0, 0);
  211.   if (new_sock == INVALID_SOCKET)
  212.   {
  213.     int rc = WSAGetLastError();
  214.     if(rc==WSAEWOULDBLOCK)
  215.     {
  216.       return 0; // non-blocking call, no request pending
  217.     }
  218.     else
  219.     {
  220.       throw "Invalid Socket";
  221.     }
  222.   }
  223.  
  224.   Socket* r = new Socket(new_sock);
  225.   return r;
  226. }
  227.  
  228.  
  229. SocketClient::SocketClient(const std::string& host, int port) : Socket()
  230. {
  231.   std::string error;
  232.  
  233.   hostent *he;
  234.   if ((he = gethostbyname(host.c_str())) == 0)
  235.   {
  236.     error = strerror(errno);
  237.     throw error;
  238.   }
  239.  
  240.   sockaddr_in addr;
  241.   addr.sin_family = AF_INET;
  242.   addr.sin_port = htons(port);
  243.   addr.sin_addr = *((in_addr *)he->h_addr);
  244.   memset(&(addr.sin_zero), 0, 8);
  245.  
  246.   if (::connect(s_, (sockaddr *) &addr, sizeof(sockaddr)))
  247.   {
  248.     error = strerror(WSAGetLastError());
  249.     throw error;
  250.   }
  251. }
  252.  
  253.  
  254. SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type)
  255. {
  256.   FD_ZERO(&fds_);
  257.   FD_SET(const_cast<Socket*>(s1)->s_,&fds_);
  258.   if(s2)
  259.   {
  260.     FD_SET(const_cast<Socket*>(s2)->s_,&fds_);
  261.   }    
  262.  
  263.   TIMEVAL tval;
  264.   tval.tv_sec  = 0;
  265.   tval.tv_usec = 1;
  266.  
  267.   TIMEVAL *ptval;
  268.   if(type==NonBlockingSocket)
  269.   {
  270.     ptval = &tval;
  271.   }
  272.   else
  273.   {
  274.     ptval = 0;
  275.   }
  276.  
  277.   if (select (0, &fds_, (fd_set*) 0, (fd_set*) 0, ptval) == SOCKET_ERROR)
  278.     throw "Error in select";
  279. }
  280.  
  281. bool SocketSelect::Readable(Socket const* const s)
  282. {
  283.   if (FD_ISSET(s->s_,&fds_)) return true;
  284.   return false;
  285. }
  286.  
  287.  


y el socket.h

Código: Text
  1. #ifndef SOCKET_H
  2. #define SOCKET_H
  3.  
  4. #include <WinSock2.h>
  5. #include <string>
  6.  
  7. enum TypeSocket {BlockingSocket, NonBlockingSocket};
  8.  
  9. class Socket {
  10.     public:
  11.     
  12.       virtual ~Socket();
  13.       Socket(const Socket&);
  14.       Socket& operator=(Socket&);
  15.     
  16.       std::string ReceiveLine();
  17.       std::string ReceiveBytes();
  18.     
  19.       void   Close();
  20.     
  21.       // The parameter of SendLine is not a const reference
  22.       // because SendLine modifes the std::string passed.
  23.       void   SendLine (std::string);
  24.     
  25.       // The parameter of SendBytes is a const reference
  26.       // because SendBytes does not modify the std::string passed
  27.       // (in contrast to SendLine).
  28.       void   SendBytes(const std::string&);
  29.     
  30.     protected:
  31.       friend class SocketServer;
  32.       friend class SocketSelect;
  33.     
  34.       Socket(SOCKET s);
  35.       Socket();
  36.     
  37.     
  38.       SOCKET s_;
  39.     
  40.       int* refCounter_;
  41.     
  42.     private:
  43.       static void Start();
  44.       static void End();
  45.       static int  nofSockets_;
  46.  
  47. };
  48.  
  49.  
  50. class SocketClient : public Socket
  51. {
  52.     public:
  53.       SocketClient(const std::string& host, int port);
  54. };
  55.  
  56.  
  57.  
  58. class SocketServer : public Socket
  59. {
  60.     public:
  61.       SocketServer(int port, int connections, TypeSocket type=BlockingSocket);
  62.     
  63.       Socket* Accept();
  64. };
  65.  
  66.  
  67. class SocketSelect {
  68.   public:
  69.     SocketSelect(Socket const * const s1, Socket const * const s2=NULL, TypeSocket type=BlockingSocket);
  70.  
  71.     bool Readable(Socket const * const s);
  72.  
  73.   private:
  74.     fd_set fds_;
  75. };
  76.  
  77. #endif
  78.  
  79.  


Con eso ya se puede compilar el programa creando un proyecto con esos archivos, y el error obtenido es el que no es un uso válido en un miembro estático.

A ver si pudiesemos encontrar la solución, muchisimas gracias.

pd: La clase socket, fue realizada por René Nyffenegger.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #9 en: Jueves 8 de Noviembre de 2007, 09:22 »
0
Cita de: "captaindanieo"
Si pongo Answer como estátito cobtengo el error siguiente:

invalid use of member L2cap::escuchando in static member function  :(
Evidentemente y es por la razon que te decia antes:
Mientras no uses ningun variable miembro de la clase no hay problema, sino tenes que pasarle un puntero a la instancia del objeto ya que al ser una funcion estatica no tiene puntero this (no pertenece a ninguna instancia de la clase). Al ser un solo parametro el que se le puede pasar a un hilo normalmente se usa una estructura con varios campos, en este caso por ejemplo el this y el a. Sino creas otro miembro en la clase L2cap y antes de crear el hilo le asignas a ese campo el valor de a y solo tenes que pasar this para trabajar.

Una posible solucion seria hacer esto:

Primer agregamos un campo a L2cap:
Código: Text
  1.  
  2. private:    
  3.   // VARIABLES GLOBALES
  4.   Socket *s;
  5.   bool escuchando;
  6.  
  7.  

Al crear el hilo pasamos lo que viene a ser el puntero this (la direccion en memoria del objeto):
Código: Text
  1.  
  2. s=in.Accept(); //el nuevo campo de la clase que declaramos
  3. _beginthreadex(0,0,Answer,(void*)this,0,&ret); //pasamos this
  4.  
  5.  

Entonces en Answer ya no recibimos un puntero a Socket sino uno a L2cap:
Código: Text
  1.  
  2. unsigned __stdcall L2cap::Answer(void* a)
  3. {
  4.   L2cap *thisL2cap = (L2cap*)a;
  5. //Ahora podes usar thisL2cap para acceder tanto a escuchando como a s o cualquier otro campo
  6. }
  7.  
  8.  

Por cierto, no uses #include <> con tus archivos ya que estan en el mismo directorio, usa #include "".

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

captaindanieo

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #10 en: Jueves 8 de Noviembre de 2007, 14:54 »
0
Muchas gracias Eternal Idol.

He realizado las modificaciones correspondientes, pero obtengo un error en _beginthreadex.

In member function 'void L2cap:: Server(int,char**)'

argument of type 'unsigned int (L2cap:: )(void*) does not match 'unsigned int (*)(void*)'

Build error (L2cap.o) Error 1


 :(

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #11 en: Jueves 8 de Noviembre de 2007, 15:32 »
0
Cita de: "captaindanieo"
Muchas gracias Eternal Idol.

He realizado las modificaciones correspondientes, pero obtengo un error en _beginthreadex.

In member function 'void L2cap:: Server(int,char**)'

argument of type 'unsigned int (L2cap:: )(void*) does not match 'unsigned int (*)(void*)'

Build error (L2cap.o) Error 1


 :(
¿Estas seguro de que estas usando el ultimo codigo? Ese es el error que se obtiene cuando la funcion NO es estatica ...

¿Que compilador estas usando? Tanto con VC++ como con gcc bajo Windows lo compila bien ... cuando se usa:

Código: Text
  1.  
  2. static unsigned __stdcall L2cap::Answer(void* a);
  3.  
  4.  

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

captaindanieo

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #12 en: Jueves 8 de Noviembre de 2007, 15:51 »
0
Estoy usando devc++.

Sin embargo creo que había cometido algún error y se me había olvidado algún static en el código.

Parece que ahora funciona.

Para acceder a las variables y métodos de mi clase, lo único que tengo ue hacer es hacerlo mediante:

if (thisL2cap->escuchando);

por ejemplo, ¿no?

Y para acceder a los métodos de la clase socket, tendré que usar la variable socket creada en L2cap, por lo que el acceso deberá ser:

    std::string r = thisL2cap->s->ReceiveBytes();  

por ejemplo.


¿Está bien así?

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #13 en: Jueves 8 de Noviembre de 2007, 15:56 »
0
Cita de: "captaindanieo"
Estoy usando devc++.

Sin embargo creo que había cometido algún error y se me había olvidado algún static en el código.

Si, el necesario  ;)

Cita de: "captaindanieo"
¿Está bien así?

Si, probalo  :kicking:

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

captaindanieo

  • Miembro activo
  • **
  • Mensajes: 46
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #14 en: Jueves 8 de Noviembre de 2007, 16:19 »
0
Un millón de gracias Eternal Idol. Ya compila. Yo creo que todo va bien. Si el acceso a los elementos es como me has confirmado, entonces está perfecto :).

Llevaba atascado varias semanas en ese punto, y nadie había podido ayudarme.

Muchísimas gracias de nuevo!  :kicking:

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Problema Con _beginthreadex En Una Clase
« Respuesta #15 en: Jueves 8 de Noviembre de 2007, 16:27 »
0
Cita de: "captaindanieo"
Un millón de gracias Eternal Idol. Ya compila. Yo creo que todo va bien. Si el acceso a los elementos es como me has confirmado, entonces está perfecto :).

Llevaba atascado varias semanas en ese punto, y nadie había podido ayudarme.

Muchísimas gracias de nuevo!  :kicking:
De nadas, es un problema que tarde o temprano uno se encuentra en C++  B)

Otro caso.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.