Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > ASM y Microcontroladores
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-04-2009
clavijo83 clavijo83 is offline
Registrado
 
Registrado: abr 2009
Posts: 8
Poder: 0
clavijo83 Va por buen camino
Error de lectura de puerto serie "Memoria Insuficiente".

hola a todos.

Tengo una dll que uso para comunicar un dispositivo conectado al puerto COM con un programa ya realizado, la funcion que hace la lectura del puerto funciona perfectamente desde un formulario interno de la misma DLL, pero al hacer el llamado de la funcion de lectura del puerto desde el programa, realiza la funcion de apertura del puerto, la funcion del dispositivo para realizar la transaccion, pero cuando va a leer el puerto sale un mensaje que dice "memoria Insuficiente". estuve viendo con un monitor de puerto que realmente se envia los datos.

aqui esta el codigo de la DLL obviamente en DELPHI:

Código Delphi [-]

function leebanda:string;stdcall;
var
sTmp: string;
c1,rebut: integer;
chBuffer: array[0..150] of char;
NumberOfBytesRead: dword;
begin
//abro el puerto
AbrirPuerto('COM1','1200','E','7','1');
//mensaje de solicitud de lectura
banda;

repeat
  rebut:=0;
  repeat
  if ComFile=INVALID_HANDLE_VALUE then
  Exit;
   if not ReadFile(ComFile, chBuffer[rebut],1, NumberOfBytesRead, nil) then
   raise Exception.Create('Imposible leer datos desde el puerto');
    for c1:= 0 to NumberOfBytesRead - 1 do
     sTmp:= sTmp+chBuffer[c1];
    until rebut<100 ;
 if chBuffer[rebut]=chr(04) then
  begin
  CerrarPuerto;
    //libero memoria
    SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
    break;
  end;
until rebut=100;
result:=sTmp;

end;

procedure Banda;stdcall;
var
  Texto:string;
  Bytes: DWORD;
begin
  //mensaje de seleccion de llave maestra
  Texto:=  #2 + 'Z1'+ #3 + 'h'+#2 + 'Z9'+'03'+ #3 + 'c';
  WriteFile(ComFile, Texto[1], Length(Texto), Bytes, nil);
  SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
end;


y aqui esta el codigo de la aplicacion que usa la DLL y desafortunadamente en ViSUAL:

Código:
Private Declare Function leebanda Lib "C:\pnp\dllcredicard.dll" () As String
Public retorno As String
Public x As String

Private Sub boton_leer_banda_Click()
    Dim txt As String
    Dim token As String
    Dim msj As String
    ' Se llama a la función del VPOS para leer la banda de tarjetas de créditos y débitos
    retorno = leebanda
    ' Se obtiene el valor del string que retorna la función del VPOS
    ' este string posee los valores de los tracks de la tarjeta a la cual se le leyo la banda
    x = retorno
    retorno = GetToken(retorno, ";") '& vbCrLf
    Do
        token = GetToken("", ";")
        If token = "" Then Exit Do
        retorno = retorno  '& vbCrLf
        txt = token
    Loop
        ' Se asigna en la box de texto el valor de los diferentes tracks
        If retorno <> "" Then
            var = InStr(1, retorno, "?")
            msj = Mid(retorno, 2, var - 2)
            txt_track1.Text = msj
        Else
            txt_track1.Text = ""
        End If
        If txt <> "" Then
            var = InStr(1, txt, "?")
            msj = Mid(txt, 1, var - 2)
            txt_track2.Text = msj
        Else
            txt_track2.Text = ""
        End If
End Sub

' Esta función parte el string de acuerdo a un caracter de separación que se le pasa en su invocación
Public Function GetToken(new_txt As String, delimiter As String) As String
Static txt As String
Dim pos As Integer

    ' Save new text.
    If new_txt <> "" Then txt = new_txt

    pos = InStr(txt, delimiter)
    If pos < 1 Then pos = Len(txt) + 1
    GetToken = Left$(txt, pos - 1)
    pos = Len(txt) - pos + 1 - Len(delimiter)
    If pos < 1 Then
        txt = ""
    Else
        txt = Right$(txt, pos)
    End If
End Function

Última edición por clavijo83 fecha: 03-04-2009 a las 20:43:20. Razón: no esta tomando la etiqueta [DELPHI]
Responder Con Cita
  #2  
Antiguo 03-04-2009
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
¿Porque lo tienes aislado en una DLL y no utilizas el MSComm para leerlo directamente desde VB?...

Tu código esta incompleto, igualmente veo un error evidente: No puedes retornar un string en la función leebanda si pretendes leerlo desde VB, ya que string es un tipo propietario de pascal, donde utiliza uno o dos bytes de longitud, para pasárselo a VB te recomiendo que retornes un “Null terminated char” (PChar)

PD: Te recomiendo emplolijar un poco la identación de tu código, se hace algo incomprensible.

Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #3  
Antiguo 04-04-2009
clavijo83 clavijo83 is offline
Registrado
 
Registrado: abr 2009
Posts: 8
Poder: 0
clavijo83 Va por buen camino
hola Federico.

bueno lo tengo aislado porque hay muchos programas que usan esta DLL, lo que estoy haciendo es mi propia version de la DLL, por lo que tengo que dejarle las mismas funciones y procedimientos o mas bien dejarle los mismo nombres.

estuve haciendo la DLL en visual para usar el MSComm y realmente habian mas problemas, en algunos lados me reconocia la DLL en otros no. por lo que opte a hacerla en delphi que es donde esta hecha actualmente la DLL original.

porque dices que mi codigo esta incompleto? solo hace falta ahi la estructura de la funcion "AbrirPuerto". aquie te la agrego.

Código Delphi [-]
procedure AbrirPuerto(Puerto,velocidad,paridad,tamano,parada: String);stdcall;
const
  RxBufferSize = 256;
  TxBufferSize = 256;
var
  DCB: TDCB;
  Config: string;
  CommTimeouts: TCommTimeouts;
  DeviceName: array[0..80] of Char;
  begin

  cerrarpuerto;

  StrPCopy(DeviceName, (Puerto));

  ComFile := CreateFile(DeviceName, GENERIC_READ or GENERIC_WRITE, 0,  nil, OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,  0);

  if ComFile = INVALID_HANDLE_VALUE then
    begin
    Result := False
    end
  else
    begin
    Result := True;
    end;

 Result := True;

  if not SetupComm(ComFile, RxBufferSize, TxBufferSize) then
    Result := False;

  if not GetCommState(ComFile, DCB) then
    Result := False;

  //definir la configuracion del Puerto

  Config := 'baud='+ velocidad +' parity='+ paridad + 'data='+ tamano + ' stop='+parada;

  if not BuildCommDCB(@Config[1], DCB) then
    Result := False;

  if not SetCommState(ComFile, DCB) then
    Result := False;

  with CommTimeouts do
  begin
    ReadIntervalTimeout         := $FFFFFFFF; //0
    ReadTotalTimeoutMultiplier  := 0;
    ReadTotalTimeoutConstant    := 1000;//1000
    WriteTotalTimeoutMultiplier := 0;
    WriteTotalTimeoutConstant   := 1000;//1000
  end;

  if not SetCommTimeouts(ComFile, CommTimeouts) then
    Result := False;

    SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
end;

estuve tratando cambiandole el tipo de dato a PChar y bueno al hacer la lectura la primera vez no sale nada, hago la lectura nuevamente y se sale solo de la aplicacion.
Responder Con Cita
  #4  
Antiguo 06-04-2009
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Sigo viendo incoherente te código, entiendo que lo debes haber recortado de tu aplicación. Fijate el tratamiento que haces con la variable Result, primero que no se trata de una función sino de un procedure, luego le asignas un valor y posteriormente lo sobreescribes a True. Los parámetros de este procedimiento siguen siendo "String". Ademas, veo que en las funciones anteriores no se le da importancia al resultado de "AbirPuerto".

Hice un breve resumen de la DLL si cambiar las partes que no entiendo del código, y no me falla, salvo que no exista el puerto o este este abierto.
Código Delphi [-]
library dllcredicard;

uses
  SysUtils,
  Classes,
  Windows,
  Math;

var
  hComFile: THandle;

procedure CerrarPuerto;
begin
  CloseHandle(hComFile);
end;

function AbrirPuerto(Puerto, velocidad, paridad, tamano, parada: PChar): boolean;
const
  RxBufferSize = 256;
  TxBufferSize = 256;
var
  DCB: TDCB;
  Config: string;
  CommTimeouts: TCommTimeouts;
begin
  CerrarPuerto;

  hComFile := CreateFile(Puerto, GENERIC_READ or GENERIC_WRITE, 0,  nil,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,  0);

  Config := 'baud=' + velocidad + ' parity=' + paridad + 'data=' + tamano + ' stop=' + parada;

  with CommTimeouts do
  begin
    ReadIntervalTimeout         := $FFFFFFFF;
    ReadTotalTimeoutMultiplier  := 0;
    ReadTotalTimeoutConstant    := 1000;
    WriteTotalTimeoutMultiplier := 0;
    WriteTotalTimeoutConstant   := 1000;
  end;

  Result :=(hComFile <> INVALID_HANDLE_VALUE) and
            SetupComm(hComFile, RxBufferSize, TxBufferSize) and
            GetCommState(hComFile, DCB) and
            BuildCommDCB(@Config[1], DCB) and
            SetCommState(hComFile, DCB) and
            SetCommTimeouts(hComFile, CommTimeouts);
end;

procedure Banda;stdcall;
var
  Bytes: DWORD;
const
  Texto = #2'Z1'#3'h'#2'Z903'#3'c';
begin
  WriteFile(hComFile, Texto[1], Length(Texto), Bytes, nil);
end;

function leebanda(var Buff: PChar; Size: DWORD): DWORD; stdcall;
var
  sTmp: string;
  c1,rebut: integer;
  chBuffer: array[0..150] of char;
  NumberOfBytesRead: dword;
begin
  Result := 0;
  if AbrirPuerto('COM4','19200','N','8','2') then
    try
      Banda;
      repeat
        rebut:=0;
        repeat
          if hComFile=INVALID_HANDLE_VALUE then
            Exit;

          if not ReadFile(hComFile, chBuffer[rebut],1, NumberOfBytesRead, nil) then
          begin
            Result := INVALID_HANDLE_VALUE;

          end else
            for c1 := 0 to NumberOfBytesRead - 1 do
              sTmp:= sTmp + chBuffer[c1];

        until (rebut<100) and (Result = 0);

        if chBuffer[rebut]=chr(04) then
          CerrarPuerto;

      until (rebut=100) and (Result = 0);

      if Result = 0 then
      begin
        Result := Length(sTmp);
        StrLCopy(Buff, @sTmp[1], Min(Size, Result));
      end;
    finally
      CerrarPuerto;
    end;
end;

exports
  leebanda;

begin
end.
Cita:
Private Declare Function leebanda Lib "dllcredicard.dll" (ByRef Buff As String, Size As Long) As Long

Private Function DoLeeBanda() As String
Dim Buff As String * 255
Dim lLen As Long
lLen = leebanda(Buff, 255)
DoLeeBanda = Left$(Buff, lLen)
End Function

Private Sub boton_leer_banda_Click()
Caption = Now & ">" & DoLeeBanda & "<"
End Sub
Saludos!
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #5  
Antiguo 06-04-2009
clavijo83 clavijo83 is offline
Registrado
 
Registrado: abr 2009
Posts: 8
Poder: 0
clavijo83 Va por buen camino
hola federico bueno la verdad ya me funciono ya retorna un valor la funcion llebanda, la funcion quedo asi:

Código Delphi [-]
function leebanda:PChar;stdcall;
var
  sTmp:String;
  PCharString: array[0..255] of Char;
  c1,rebut: integer;
  chBuffer: array[0..150] of char;
  NumberOfBytesRead: dword;
begin
//abro el puerto
  AbrirPuerto('COM1','1200','E','7','1');
//mensaje de solicitud de lectura
  banda;
repeat
  rebut:=0;
    repeat
      if ComFile=INVALID_HANDLE_VALUE then
        Exit;
        if not ReadFile(ComFile, chBuffer[rebut],1, NumberOfBytesRead, nil) then
          raise Exception.Create('Imposible leer datos desde el puerto');
          for c1:= 0 to NumberOfBytesRead - 1 do
          sTmp:= sTmp+chBuffer[c1];
    until rebut<100 ;
      if chBuffer[rebut]=chr(04) then
      begin
        CerrarPuerto;
        //libero memoria
        SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
        break;
      end;
until rebut=100;

sTmp:=Trim(sTmp);
sTmp:=copy(sTmp,7,(length(sTmp)-9));
Result := StrPCopy(PCharString, sTmp);
end;

pero ahora hay un problema en el codigo de visual:

Código:
Private Sub boton_leer_banda_Click()
    Dim txt As String
    Dim token As String
    Dim msj As String
    ' Se llama a la función del VPOS para leer la banda de tarjetas de créditos y débitos
    retorno = leebanda
    ' Se obtiene el valor del string que retorna la función del VPOS
    ' este string posee los valores de los tracks de la tarjeta a la cual se le leyo la banda
    'x = retorno
    retorno = GetToken(retorno, ";") '& vbCrLf
    Do
        token = GetToken("", ";")
        If token = "" Then Exit Do
        retorno = retorno  '& vbCrLf
        txt = token
    Loop
        ' Se asigna en la box de texto el valor de los diferentes tracks
        If retorno <> "" Then
            var = InStr(1, retorno, "?")
            msj = Mid(retorno, 2, var - 2) 'AQUI APARECE EL ERROR
            txt_track1.Text = msj
        Else
            txt_track1.Text = ""
        End If
        If txt <> "" Then
            var = InStr(1, txt, "?")
            msj = Mid(txt, 1, var - 2)
            txt_track2.Text = msj
        Else
            txt_track2.Text = ""
        End If
End Sub
me sale el siguiente error: ERROR '5' EN TIEMPO DE EJECUCION. LLAMADA A PROCEDIMIENTO O ARGUMENTO NO VALIDO.
Responder Con Cita
  #6  
Antiguo 06-04-2009
clavijo83 clavijo83 is offline
Registrado
 
Registrado: abr 2009
Posts: 8
Poder: 0
clavijo83 Va por buen camino
hola federico bueno la verdad ya me funciono ya retorna un valor la funcion llebanda, la funcion quedo asi:

Código Delphi [-]
function leebanda:PChar;stdcall;
var
  sTmp:String;
  PCharString: array[0..255] of Char;
  c1,rebut: integer;
  chBuffer: array[0..150] of char;
  NumberOfBytesRead: dword;
begin
//abro el puerto
  AbrirPuerto('COM1','1200','E','7','1');
//mensaje de solicitud de lectura
  banda;
repeat
  rebut:=0;
    repeat
      if ComFile=INVALID_HANDLE_VALUE then
        Exit;
        if not ReadFile(ComFile, chBuffer[rebut],1, NumberOfBytesRead, nil) then
          raise Exception.Create('Imposible leer datos desde el puerto');
          for c1:= 0 to NumberOfBytesRead - 1 do
          sTmp:= sTmp+chBuffer[c1];
    until rebut<100 ;
      if chBuffer[rebut]=chr(04) then
      begin
        CerrarPuerto;
        //libero memoria
        SetProcessWorkingSetSize(GetCurrentProcess, $FFFFFFFF, $FFFFFFFF);
        break;
      end;
until rebut=100;

sTmp:=Trim(sTmp);
sTmp:=copy(sTmp,7,(length(sTmp)-9));
Result := StrPCopy(PCharString, sTmp);
end;

pero ahora hay un problema en el codigo de visual:

Código:
Private Sub boton_leer_banda_Click()
    Dim txt As String
    Dim token As String
    Dim msj As String
    ' Se llama a la función del VPOS para leer la banda de tarjetas de créditos y débitos
    retorno = leebanda
    ' Se obtiene el valor del string que retorna la función del VPOS
    ' este string posee los valores de los tracks de la tarjeta a la cual se le leyo la banda
    'x = retorno
    retorno = GetToken(retorno, ";") '& vbCrLf
    Do
        token = GetToken("", ";")
        If token = "" Then Exit Do
        retorno = retorno  '& vbCrLf
        txt = token
    Loop
        ' Se asigna en la box de texto el valor de los diferentes tracks
        If retorno <> "" Then
            var = InStr(1, retorno, "?")
            msj = Mid(retorno, 2, var - 2) 'AQUI APARECE EL ERROR
            txt_track1.Text = msj
        Else
            txt_track1.Text = ""
        End If
        If txt <> "" Then
            var = InStr(1, txt, "?")
            msj = Mid(txt, 1, var - 2)
            txt_track2.Text = msj
        Else
            txt_track2.Text = ""
        End If
End Sub
me sale el siguiente error: ERROR '5' EN TIEMPO DE EJECUCION. LLAMADA A PROCEDIMIENTO O ARGUMENTO NO VALIDO.

Y me sale en la funcion MID de visual, porque sera eso? ah no uso la otra funcion que me pusiste de leebanda, porque no puedo cambiarle la estructura. asi hacen la llamada en los programas que ya usan esta DLL.
Responder Con Cita
  #7  
Antiguo 06-04-2009
Avatar de delphi.com.ar
delphi.com.ar delphi.com.ar is offline
Federico Firenze
 
Registrado: may 2003
Ubicación: Buenos Aires, Argentina *
Posts: 5.932
Poder: 26
delphi.com.ar Va por buen camino
Cita:
Empezado por clavijo83 Ver Mensaje
me sale el siguiente error: ERROR '5' EN TIEMPO DE EJECUCION. LLAMADA A PROCEDIMIENTO O ARGUMENTO NO VALIDO.

Y me sale en la funcion MID de visual, porque sera eso? ah no uso la otra funcion que me pusiste de leebanda, porque no puedo cambiarle la estructura. asi hacen la llamada en los programas que ya usan esta DLL.
Si var llega a tener valor "0" entonces el segundo parámetro sería "-2", y produciría ese error, prueba esto en el inmediato:
Cita:
? MID$("", 2, -2)
__________________
delphi.com.ar

Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla.
Responder Con Cita
  #8  
Antiguo 08-04-2009
rodrigo-25 rodrigo-25 is offline
Registrado
 
Registrado: abr 2009
Posts: 1
Poder: 0
rodrigo-25 Va por buen camino
consulta delphi

hola chicos, soy nuevo en el sitio, y me surgio un problema en lo que es funciones en delphi.

estuve haciendo una calculadora, y precisaba sacar la raiz, entonces utilice la funcion SQRT, pero preciso saber una funcion en la cual eleve cualquier número, me de el resultado, sea cual sea a la raiz que la eleve, alguien sabe de esta funcion.

muchas gracias y espero puedan ayudarme.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Error al LLamar un DLL, "memoria Insuficiente" clavijo83 Varios 0 02-04-2009 19:34:50
Lectura Hexadecimal desde el puerto serie djemix Varios 20 09-12-2007 16:22:55
Particiones en "solo lectura " con cd_live de knoppix Diavlo Linux 1 03-10-2007 05:06:26
error de sql server "Informacion de columna clave insuficiente" jhcaboverde Conexión con bases de datos 1 17-08-2007 20:40:31
Fast Report "Fuera de memoria" BECERRA Impresión 0 25-12-2005 13:40:29


La franja horaria es GMT +2. Ahora son las 17:29:17.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi