elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Curso de javascript por TickTack


  Mostrar Mensajes
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
11  Programación / Programación C/C++ / Problema con COMMTIMEOUTS [SOLUCIONADO] en: 11 Diciembre 2014, 12:24 pm
Hola a todos. Estoy desarrollando una aplicación en la que, entre otras cosas, tengo que leer y escribir por el puerto seria. Para ello uso la WinAPI.

No consigo configurar bien los timeouts (SetCommTimeouts), yo lo que quiero es que si al intentar leer del puerto serie no hay nada, éste espere un tiempo razonable (500 ms, 1 sec.) y luego continúe con la ejecución.

He leído la documentación de microsoft, y lo que entiendo es:

- El ReadIntervalTimeout es el tiempo max. que transcurre desde que llega un byte hasta que llega el siguiente.

- El ReadTotalTimeoutMultiplier: en cada operación de lectura, la cantidad de bytes a leer se multiplica por este valor. No entiendo para que sirve esto.

- El ReadTotalTimeoutConstant: este valor se suma al resultado de multiplicar el número de bytes a leer por el ReadTotalTimeoutMultiplier. No entiendo para que sirve esto.

De lo mencionado, ¿hay algo correcto?

¿Qué valores debo dar a las variables anteriores para tener por ej. 500 milisegundos de timeout en total?

Saludos, gracias.



12  Programación / Programación C/C++ / Re: Evitar quedarse bloqueado al leer del puerto serie (C++ WinAPI) en: 8 Diciembre 2014, 14:36 pm
Hola, gracias por la respuesta.

No me refería a que el hilo se quedase bloqueado, quiero decir que hacer ReadFile sin OVERLAPPED si se queda bloqueado, lo que quiero es tener una función que haga ReadFile a lo que haya en el buffer, y si no hay nada, que no se quede bloqueado.

Para ello creo que la manera de hacerlo es con OVERLAPPED, y al hacer ReadFile internamente se lanza un hilo, si yo lo he entendido bien.

Mi problema entonces es que no uso bien el OVERLAPPED porque la función ReadFile me devuelve un error que no es ERROR_IO_PENDING (que es lo que debería devolverme si no hay nada en el buffer).

He seguido intentándolo, pero aún no ha habido suerte.

Saludos.

EDITO:
He cambiado el CreateFile para ponerlo en lectura compartida y FILE_FLAG_OVERLAPPED y algunos otros errores que tenía, ahora el readExisting()
"parece" que funciona bien, porque al hacerlo me devuelve una cadena vacía.
El problema es que con el emulador que uso, al hacer write sobre COM3 (que está conectado a COM4), si no tengo abierto el hyperterminal no escribe nada en el buffer, no se por qué. El caso es que no puedo probarlo del todo pero creo que ya va bien, gracias por la respuesta. Si consigo comprobar que todo funciona subo el código para el que lo quiera ver.

Saludos.


EDITO 2:
Resulta que si hacemos el CreateFile con FILE_FLAG_OVERLAPPED ya no se pueden hacer lecturas síncronas. Tiene que ser lo uno o lo otro. La única solución que veo entonces (para hacer una clase que tenga métodos síncronos y asíncronos) es pasar del overlapped y crearme yo mis propios hilos. Si hay alguna manera mejor de hacerlo, agradeceré que me lo expliquen. No tengo claro si será mejor idea andar con hilos o, cada vez que quiera hacer el readExisting(), cambiar el readtimeout del puerto a 0.

Saludos.
13  Programación / Programación C/C++ / Evitar quedarse bloqueado al leer del puerto serie (C++ WinAPI) en: 7 Diciembre 2014, 22:35 pm
Hola a todos.

Estoy haciendo una clase en C++ con funcionalidad para leer y escribir de distintas maneras en el puerto serie (con la Win32 API).
Como no tengo nada que use puerto serie, para hacer las pruebas estoy usando un emulador de puertos serie (com0com).

Estoy intentando implementar un método que lea todo lo que hay actualmente en el buffer del puerto serie, y si no hay nada, que no se quede bloqueado esperando.

He intentado hacerlo con OVERLAPPED pero, aparte de que no me ha funcionado, no me gusta la idea de tener que lanzar un hilo cada vez que quiero hacer esta opración.

Aquí el código que he escrito:
Código:
port = CreateFile(
string2LPCTSTR(this->portName), //\\\\.\\COM4"
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // default security attributes
OPEN_EXISTING,
0,
NULL
);
if (port == INVALID_HANDLE_VALUE)
throw SerialPortNativeIOException("Port value is INVALID_HANDLE_VALUE");

DCB portConfig;
if (GetCommState(port, &portConfig) == 0){
closeConnection();
this->port=INVALID_HANDLE_VALUE;
throw SerialPortNativeIOException("Error trying to get comm state");
}

setPortConfig(portConfig); //Esto simplemente asigna valores...

if(SetCommState(port, &portConfig)==0){
closeConnection();
this->port=INVALID_HANDLE_VALUE;
throw SerialPortNativeIOException("Error trying to set comm state");
}

setTimeoutConfig(); //Esto simplemente asigna valores...

if(SetCommTimeouts(port, &timeoutConfig)==0){
closeConnection();
this->port=INVALID_HANDLE_VALUE;
throw SerialPortNativeIOException("Error trying to set comm timeout config.");
}
this->connected=true;

...

std::string SerialPortNative::readExisting(){
ulong readBytes=0;
OVERLAPPED oR = {0};
oR.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
if(!ReadFile(this->port,this->buffer,READEXISTING_BUFFER_SIZE,&readBytes,&oR))
if(GetLastError() != ERROR_IO_PENDING)
throw SerialPortNativeIOException("Error reading from serial port");
return string(this->buffer,0,readBytes);
}

Al usar el método 'readExisting()' la lectura da error y no es ERROR_IO_PENDING, es el error con código 3 (ERROR_PATH_NOT_FOUND).

Ya he leído la documentación y ejemplos de msdn.microsoft y he googleado, pero no consigo hacerlo funcionar.

¿Qué puedo hacer? Gracias, saludos.
14  Programación / Scripting / Modificar código en tiempo de ejecución en función de la versión de python en: 7 Noviembre 2014, 09:32 am
Hola a todos.

Tengo que hacer un proyecto en python que sea compatible con la versión 2.7. hasta ahora usaba esta versión pero he llegado a un punto del código en el que me vendría genial poder usar @abstraclassmethod que solo está en la versión 3 en adelante.

Lo que quiero hacer es, dentro del código, tener en una variable la versión del intérprete y, en función de si es mayor o menor que 3, hacer una cosa u otra.

Aquí un fragmento de código:
Código:
#dentro de ModuloA.py

__INTERPRETER_VERSION = float(sys.version.split(" ")[0])
if(__INTERPRETER_VERSION >= 3):
    from abc import abstractclassmethod

class AAA(object):
....
     if(__INTERPRETER_VERSION < 3):
        @classmethod
        def createPacket(cls, bArray, escaped):
            raise NotImplementedError("This method is not implemented in this class. See inheritance.")
    else:
        @abstractclassmethod
        def createPacket(cls, bArray, escaped):
            pass

El problema es que al ejecutar el código me dice que la variable _ModuloA__INTERPRETER_VERSION no está definida. Esto ya se que es por los dos guiones bajos.

Mis preguntas son:
1 - ¿Es buena idea hacer lo que estoy haciendo? ¿pongo simplemente la versión del 2.7 y ya está?

2 - ¿Cómo hago para definir una variable privada dentro del módulo y accederla dentro de las clases de dicho módulo?

Gracias, saludos.
15  Programación / .NET (C#, VB.NET, ASP) / Re: Problema con BitBlt y C++/CLI en: 19 Octubre 2014, 16:00 pm
Hola de nuevo, respecto al IntPtr, tiene un método toPointer() que devuelve void*, y HDC es un void* realmente.
De todas formas ya he solucionado el error, el problema es que ahora no veo por pantalla lo que dibujo.
Adjunto el nuevo código en el que BitBlt() da error 0 (todo ok), por algún motivo el PictureBox no se actualiza bien:

Código
  1. [DllImport("gdi32.dll", CallingConvention = CallingConvention::StdCall, SetLastError = true)]
  2. extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
  3. IntPtr hdcSrc, int nXSrc, int nYSrc, long dwRop);
  4.  
  5. int main(array<System::String ^> ^args){
  6. Graphics ^gph = nullptr;
  7. try{
  8. //Get a test image and it's parameters
  9. Bitmap ^image = gcnew Bitmap("./img/Simple_tux0.bmp");
  10. int iWidth = image->Width;
  11. int iHeigth = image->Height;
  12. PixelFormat pxF = image->PixelFormat;
  13.  
  14. //Prepare a PictureBox, which will be given as parameter to Windows Form.
  15. //It has an image that's my "draw area".
  16. PictureBox ^pb = gcnew PictureBox();
  17. pb->SizeMode = PictureBoxSizeMode::Normal;
  18. pb->Size = Drawing::Size(iWidth, iHeigth);
  19. pb->Location = Drawing::Point(0, 0);
  20. Bitmap ^drawArea = gcnew Bitmap(pb->Width, pb->Height);
  21. pb->Image = drawArea;
  22.  
  23. //Get bitmap
  24. IntPtr prueba = image->GetHbitmap();
  25.  
  26. //Create my device context, where i will paint my lines.
  27. gph = Graphics::FromImage(drawArea);
  28. IntPtr deviceContext = gph->GetHdc();
  29.  
  30.  
  31. //Paint only 50 lines of the source Bitmap.
  32. BOOL b = BitBlt((HDC)deviceContext.ToPointer(), 0, 0, iWidth, 50,
  33. (HDC)prueba.ToPointer(), 0, 0, SRCCOPY);
  34.  
  35. //Get the error:
  36. unsigned long err = GetLastError();
  37. Console::WriteLine("error: {0}", err); //error 6 : Invalid Handle
  38.  
  39. //Refresh
  40. pb->Invalidate();
  41. pb->Refresh();
  42.  
  43. //Create windows form with the PictureBox to display my 50 lines.
  44. MyForm ^f = gcnew MyForm(pb);
  45. Application::Run(f);
  46. Application::Exit();
  47. }
  48. finally{
  49. if (gph != nullptr){
  50. gph->ReleaseHdc();
  51. delete gph;
  52. }
  53.  
  54. }
  55. return 0;
  56. }
  57.  

¿Qué hago mal?

Saludos, gracias.
16  Programación / .NET (C#, VB.NET, ASP) / Problema con BitBlt y C++/CLI en: 17 Octubre 2014, 21:42 pm
Hola a todos.

Tengo que usar la función BitBlt() en código C++/CLI. Lo he intentado de muchas formas y no consigo que funcione. Me da el error código 6 (invalid handle).
He leído bastantes posts etc. por internet, y para empezar veo que nadie que use esta función tiene que hacer un casting de IntPtr a HDC. Adjunto el código (comentado en inglés)

Código
  1. /*
  2. 1 - Get a bmp image from hard drive( i have it).
  3.  
  4. 2 - Copy it to byte array, or get its internal array, i have tested both ways (method1 and method2 in comments).
  5.  
  6. 3 - Prepare a PicutreBox and obtain from it my context device.
  7.  
  8. 4 - Use BitBlt function to copy only first 50 lines of the initial bitmap.
  9.  
  10. 5 - Display it in a windows form.
  11. */
  12.  
  13. #include "stdafx.h"
  14. #include <Windows.h>
  15. #include "MyForm.h"
  16. #include "string.h"
  17.  
  18. using namespace System;
  19. using namespace System::Runtime::InteropServices;
  20. using namespace System::Runtime::CompilerServices;
  21. using namespace System::IO;
  22. using namespace System::Windows::Forms;
  23. using namespace System::Drawing;
  24. using namespace System::Drawing::Imaging;
  25.  
  26. using namespace ConsoleApplication1;
  27.  
  28. [DllImport("gdi32.dll", CallingConvention = CallingConvention::StdCall, SetLastError = true)]
  29. extern bool BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
  30. IntPtr hdcSrc, int nXSrc, int nYSrc, long dwRop);
  31.  
  32. int main(array<System::String ^> ^args){
  33. Graphics ^gph = nullptr;
  34. try{
  35. //Get a test image and it's parameters
  36. Bitmap ^image = gcnew Bitmap("./img/Simple_tux0.bmp");
  37. int iWidth = image->Width;
  38. int iHeigth = image->Height;
  39. PixelFormat pxF = image->PixelFormat;
  40.  
  41.  
  42. //Prepare a PictureBo, whici will be given as parameter to Windows Form.
  43. PictureBox ^pb = gcnew PictureBox();
  44. pb->SizeMode = PictureBoxSizeMode::StretchImage;
  45. pb->Size = Drawing::Size(iWidth + 10, iHeigth + 10);
  46. pb->Location = Drawing::Point(3, 3);
  47.  
  48. //Get bitmap
  49. IntPtr prueba = image->GetHbitmap();
  50.  
  51. //Create my device context, where i will paint my lines.
  52. gph = pb->CreateGraphics();
  53. IntPtr deviceContext = gph->GetHdc();
  54.  
  55.  
  56. //Paint only 50 lines of the source Bitmap.
  57. BOOL b = BitBlt((HDC)deviceContext.ToPointer(), 0, 0, iWidth, 50,
  58. (HDC)prueba.ToPointer(), 0, 0, SRCCOPY);
  59.  
  60. //Get the error:
  61. unsigned long err = GetLastError();
  62. Console::WriteLine("error: {0}", err); //error 6 : Invalid Handle
  63.  
  64. //Create windows form with the PictureBox to display my 50 lines.
  65. MyForm ^f = gcnew MyForm(pb);
  66. Application::Run(f);
  67. Application::Exit();
  68. }
  69. finally{
  70. if (gph != nullptr){
  71. gph->ReleaseHdc();
  72. delete gph;
  73. }
  74.  
  75. }
  76. return 0;
  77. }
  78.  

He intentado usar también esto:

Código
  1. [DllImport("coredll.dll", EntryPoint = "CreateCompatibleDC")]
  2. extern IntPtr CreateCompatibleDC(IntPtr hdc);
  3.  
  4. [DllImport("coredll.dll", EntryPoint = "GetDC")]
  5. extern IntPtr GetDC(IntPtr hwnd);
  6.  
  7. int main(){
  8. //...
  9. //...
  10. IntPtr dc = GetDC(deviceContext);
  11. IntPtr compDc = CreateCompatibleDC(dc);
  12.  
  13. //Paint only 50 lines of the source Bitmap.
  14. BOOL b = BitBlt((HDC)compDc.ToPointer(), 0, 0, iWidth, 50,
  15. (HDC)prueba.ToPointer(), 0, 0, SRCCOPY);
  16.  

La primera pregunta que me surge es por qué yo tengo que hacer esto:
Código:
(HDC)deviceContext.ToPointer()
Y en todos los post que leo nadie lo hace.

Saludos, gracias.
17  Programación / .NET (C#, VB.NET, ASP) / Re: Problema con modificación de un PictureBox desde el hilo generado por un Timer. en: 6 Octubre 2014, 08:57 am
Hola de nuevo, gracias por la respuesta. Primero debo aclarar que estoy seguro de que desbloqueo el bitmap.

He probado una cosa que funciona: desde el fichero fuente del formulario que uso (Form1) hago un método que usa un Timers.Timer y muestra bien las imágenes (boca abajo, no se por qué).
También he probado un método que en lugar de un Timer es un bucle con un Thread::Sleep().
Repito, de estas dos formas funciona bien.

Si traslado cualquiera de estas 2 formas a otra clase todo falla, no entiendo por qué.
Voy a copiar el código en C++/CLI (es exactamente igual que C#, sintaxis aparte), de los métodos que uso, sin Timer:
Form1 (sin usar clase aparte)
Código:
//Esta cabecera es para poder usar el método como callback del timer.
void Form1::showMyImage2(Object ^source, ElapsedEventArgs ^e){
try{
int len = 0;
unsigned char *c = this->getFrame2((String^)Form1::path + Convert::ToString(this->counter) + ".bmp", len);
BitmapData ^bmpd = this->bmp->LockBits(Drawing::Rectangle(0, 0,
this->width, this->height), ImageLockMode::ReadWrite,this->pixelFormat);
bmpd->Scan0 = (IntPtr)c;
this->bmp->UnlockBits(bmpd);
this->picBox->Image = dynamic_cast<Image^>(this->bmp);
                //Esto es para ir cambiando del frame 0 al 1, al 2 ... etc.
this->counter = (this->counter == 5 ? 0 : this->counter + 1);

}
catch (Exception ^e){
Console::WriteLine(e->InnerException);
Console::WriteLine(e->Message);
Console::WriteLine(e->StackTrace);
}
}

array<unsigned char>^ Form1::getFrame2(String ^path, int %len){
FileStream ^fs = gcnew FileStream(path, FileMode::Open, FileAccess::Read);
BinaryReader ^br = gcnew BinaryReader(fs);
FileInfo ^aux = gcnew FileInfo(path);
int nBytes = aux->Length;
Console::WriteLine("long: {0}, int: {1}", nBytes, (int)nBytes);
array<unsigned char> ^buffer = br->ReadBytes(nBytes);
len = nBytes;
pin_ptr<unsigned char> p = &buffer[0];
unsigned char *p2 = p;
return p2;
}

La otras otras clases, AbstractLiveView y LiveView. AbstracLiveView tiene un método abstracto "getNextFrame()" que implementa LiveView. Estas clases  preteden sustituir el código de Form1.

AbstractLiveView
Código:
//Esta cabcera es por usar este método como callback de un timer.
void AbstractLiveView::updateFrame(Object ^source, EventArgs ^e){
try{
this->bmpData = this->bmp->LockBits(Drawing::Rectangle(0, 0, this->width, this->heigth),
ImageLockMode::ReadWrite, this->pixelFormat);

                //Método abstracto implementado en LiveView (abajo)
this->bmpData->Scan0 = this->getNextFrame();

this->bmp->UnlockBits(this->bmpData);
this->picBox->Image = dynamic_cast<Image^>(this->bmp);
this->picBox->Update();
}
catch (Exception ^e){
Console::WriteLine(e->Message);
Console::WriteLine(e->StackTrace);
}
}

void AbstractLiveView::startLiveView(int frequency){
for (int i = 0; i <= 5; i++){
this->updateFrame(nullptr,nullptr);
}
}

LiveView (Implementación de getNextFrame())
Código:
//Obtiene el siguiente frame a dibujar (lo coge del disco duro)
IntPtr LiveView::getNextFrame(){
pin_ptr<unsigned char> p = nullptr;
try{
String ^path = pathImage + Convert::ToString(this->counter) + ".bmp";
FileStream ^fs = gcnew FileStream(path, FileMode::Open, FileAccess::Read);
BinaryReader ^br = gcnew BinaryReader(fs);
FileInfo ^aux = gcnew FileInfo(path);
uint nBytes = aux->Length;
array<unsigned char> ^buffer = br->ReadBytes(nBytes);
p = &buffer[0];
unsigned char *p2 = p;
this->counter = (this->counter == 5 ? 0 : this->counter + 1);
return (IntPtr)p;
}
catch (Exception ^e){
Console::WriteLine(e->Message);
Console::WriteLine(e->StackTrace);
return (IntPtr)p;
}

}

Saludos y gracias.
18  Programación / .NET (C#, VB.NET, ASP) / Problema con modificación de un PictureBox desde el hilo generado por un Timer. en: 6 Octubre 2014, 00:00 am
Hola a todos.

Tengo un método en C# que actualiza el contenido de un PictureBox que recibe como parámetro, algo así:
Código:
void fun(PictureBox pb){
   pb.Image = (Image)this.bitMap; //bitMap es un objeto Bitmap.
}
El caso es que esa función la uso de callback en un Timer, para ir cambiando la imagen cada cierto tiempo.
Si todo el código anterior lo meto en el mismo Windows.Form donde está el PictureBox todo va bien.
El problema es que quiero sacar todo ese código a otra clase, y usar esta clase desde mi Windows.Form. Es cuando hago esto cuando todo falla.

El error que me da es: Unexpected “Bitmap Region is already Locked”.

He buscado bastante por internet y he intentado varias cosas:
1 - He probado con Timers.Timer y con Windows.Forms.Timer .
2 - He usado el keyword 'lock' en el método de callback.
3 - He leído algo de Invoke e InvokeRequired. PictureBox tiene el InvokeRequired a 'false' así que imagino que no tiene nada que ver con usar invoke.

¿Alguien sabe qué puedo hacer?

Gracias, saludos.
19  Programación / .NET (C#, VB.NET, ASP) / Re: Streaming de bmp en C# en: 4 Octubre 2014, 20:47 pm
Podría ser pero eso ahora es lo de menos, ni siquiera se como hacer el streaming.


20  Programación / .NET (C#, VB.NET, ASP) / Re: Streaming de bmp en C# en: 4 Octubre 2014, 17:57 pm
Si, tienen que ser imágenes. Las cámaras son de fotos, no de vídeo.
Páginas: 1 [2] 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines