Erro em DLL para impressão direta p/porta serial

Delphi

11/04/2007

Construi uma dll com duas funções de teste e na qual uma função para impressão direta para porta serial mas venho tendo alguns problemas como por exemplo o seguite erro.

Access violation at address 0032485A in module ´Teste.dll´. Write of Address 0045273B

isso acontece quando envio um comando para a porta serial.

Essa dll tem duas funções uma delas é a qual eu envio os comando para Abertura da Comunicação com a porta serial e tbm o comando para impressão.

Aguardo a colaboração de alguem com mais experiência.

Obrigado.


N_informatica

N_informatica

Curtidas 0

Respostas

Ruyoutor

Ruyoutor

11/04/2007

Boa Tarde Amigo

Você esta utlizando a API do windows para abrir conexão? Esta configurando a velocidade, paridade, ByteSize e StopBits? Tem certeza que esta abrindo a conexão com a porta COM certa?

Descreva melhor os detalhes do seu problema. A pouco tempo eu fiz um programa para imprimir em uma impressora serial acredito que eu possa te ajudar


GOSTEI 0
N_informatica

N_informatica

11/04/2007

Caro amigo ruyoutor, estou usando um componente de terceiro para fazer a comunicação com a porta serial, coloquei esse componente em um DataModule e as propriedades estão configuradas corretamente.

Se o amigo puder me ajudar me enviando um exemplo com certeza isso será de grande ajuda pra muitas pessoas pq pelo q pude perceber esse assunto é muito pouco difundido.

Obrigado pela sua atenção


GOSTEI 0
Ruyoutor

Ruyoutor

11/04/2007

unit uPincipal;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, jpeg, ExtCtrls, StdCtrls, ShellAPI, Registry, IniFiles;

  function AbrirPorta        (NomePorta:String):boolean;
  Function ConfiguraControle (br: String)      :boolean;
  function ConfiguraTimeOuts                   :boolean;


type
  ...

const
  LEN_BUFFER = 100; //Tamanho dos Buffers de dados.
  BIT0       = 1;
  BIT1       = 2;
  BIT2       = 4;
  BIT3       = 8;
  BIT4       = 16;
  BIT5       = 32;
  BIT6       = 64;
  BIT7       = 128;

var
  Form1         : TForm1;
  hCom          : THANDLE;                        //Handle da Porta Serial (API).
  dcb           : TDCB;                           //Estrutura DCB (API).
  CommTimeouts  : TCOMMTIMEOUTS;                  //Estrutura TCOMMTIMEOUTS(API).

  BytesEscritos : DWORD;
  BytesLidos    : DWORD;
  BufferRecebe  : array [0..LEN_BUFFER] of char;  //Define o duffer.
  GLB_Conectado : boolean;                        //Indica se a porta já está aberta.
  GLBEnviaDados : bool;                           //Para habilitar/desabilitar o envio de dados pela serial.
  StrComandos   : AnsiString;                     //Armazena os dados lidos da Serial.

implementation

{$R *.dfm}  



//***********************************//
//  ao clicar na imagem os eventos de//
// configuração são executados e a   //
// a porta é aberta se tudo der certo// 
//***********************************//

procedure TForm1.Image10Click(Sender: TObject);
var
  Sucesso: Bool;
begin
  if not (cbxVelocidade.Text = ´´) then
  begin
    if AbrirPorta(cbxPorta.Text) = true then   //Abre a porta serial.
    begin
      GLB_Conectado := true;
      Sucesso       := ConfiguraControle(cbxVelocidade.Text);
      Sucesso       := ConfiguraTimeOuts();
      if Sucesso = false then
      begin
        GLB_Conectado := false;
        CloseHandle   (hCom);   //Fecha a porta Serial.
        ShowMessage   (´Um outro programa já está usando a porta, ou a mesma não existe!´);
      end
      else
        showmessage(´Configuração feita com sucesso´);
    end;
  end
  else
  begin
    Showmessage(´Selecione a Velocidade´);
    cbxVelocidade.SetFocus;
  end;

end;

//***************Fim*****************//

//***************************************************************************************//
//    Manda informações para porta                                                       // 
//   OBS(Esse comandos podem ou não funcionar                                            //
//  na sua impressora, a intenção e amostrar                                             //
//  como você pode mandar os dados para                                                  //
//  impressora                                                                           //
//***************************************************************************************//

procedure TForm1.Image11Click(Sender: TObject);
var
 texto : string;
 StrMens:AnsiString;
begin

  Texto := ´´                             ;
  Texto := #2764                         ;
  Texto := Texto + ´CODE93 ------1´+1310;
  Texto := Texto + 2910480             ;
  Texto := Texto + 291192              ;
  Texto := Texto + 29722               ;
  Texto := Texto + 2910772 + Chr(13)   ;
  Texto := Texto + ´1234567890123´+ 010 ;

  Texto := Texto + ´================================´;
  Texto := Texto + #271004              ;



  StrMens   := texto;                                                    //Pega a string a ser enviada.
  WriteFile ( hCom,PChar(StrMens)^,Length(StrMens), BytesEscritos, nil); //Envia string.


end;



procedure TForm1.Image12Click(Sender: TObject);
var
  Texto: String;
  StrMens: AnsiString;
begin
  Texto := ´´;
  Texto := 2764;
  Texto := Texto+27971;
  
  Texto := Texto + 273348+´* Tec Prima *´+13101310;
  Texto := Texto + 27970;
  Texto := Texto + 27330;
  Texto := Texto + 27+´G´+1+´End   : ´+27+´G´+0+´Rua Visc de Sepetiba, 65´1310;       //Pega a string a ser enviada.
  Texto := Texto + 27+´G´+1+´Cidade: ´+27+´G´+0+´Niteroi                 ´1310;
  Texto := Texto + 27+´G´+1+´Estado: ´+27+´G´+0+´Rio de Janeiro          ´1310;
  Texto := Texto + #27+´G´+1+´Tel   : ´+27+´G´+0+´(21) 2621-1104          ´1310;
  Texto := Texto + 27+´G´+1+´Fax   : ´+27+´G´+0+´(21) 2621-1104          ´1310;
  Texto := Texto + 27971     ;
  Texto := Texto + 274248    ;
  Texto := Texto + 13101310 ;
  Texto := Texto + ´================================´;

  Texto := Texto + 13101310 ;
  Texto := Texto + 27971     ;
  Texto := Texto + 273348+´Especifica´ + 135 + 148 + ´es´;
  Texto := Texto + 13101310 ;
  Texto := Texto + 27970     ;
  Texto := Texto + 27330     ;

  Texto := Texto + 27+´G´+1+´Metodo de Impress´ + 132 + ´o: ´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27972     ;
  Texto := Texto + 27+´G´+0+´Impress´+132+´o T´ + 130 + ´rmica de Linha´;
  Texto := Texto + 271002    ;
  Texto := Texto + 27970     ;

  Texto := Texto + #27+´G´+1+´Densidade de Pontos: ´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27972     ;
  Texto := Texto + 27+´G´+0+´203X203dpi(8 pontos / mm)´;
  Texto := Texto + 271002    ;
  Texto := Texto + 27970     ;

  Texto := Texto + 27+´G´+1+´Largura da Impress´ + 132 + ´o: ´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27972     ;
  Texto := Texto + 27+´G´+0+´54 mm´;
  Texto := Texto + 271002    ;
  Texto := Texto + 27970     ;

  Texto := Texto + 27+´G´+1+´Largura do Papel: ´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27972     ;
  Texto := Texto + 27+´G´+0+´58 mm´;
  Texto := Texto + 271002    ;
  Texto := Texto + 27970     ;

  Texto := Texto + 27+´G´+1+´Caracteres por Linha: ´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27972     ;
  Texto := Texto + #27+´G´+0+´42 ( 10*24 Type )´;
  Texto := Texto + 271002    ;
  Texto := Texto + 27970     ;

  Texto := Texto + 27+´G´+1+´Velocidade de Impress´ + 132 + ´o: ´;
  Texto := Texto +  1310      ;
  Texto := Texto + 27972     ;
  Texto := Texto + 27+´G´+0+´75mm / seg´;
  Texto := Texto + 271002    ;
  Texto := Texto + 27970     ;

  Texto := Texto + 27+´G´+1+´Tamanho do Buffer: ´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27972     ;
  Texto := Texto + 27+´G´+0+´5 KB´;
  Texto := Texto + 271002    ;
  Texto := Texto + 27970     ;

  Texto := Texto + 27+´G´+1+´Tipo de Interface: ´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27972     ;
  Texto := Texto + 27+´G´+0+´RS 232´;
  Texto := Texto + 271002    ;
  Texto := Texto + 27970     ;

  Texto := Texto + #27+´G´+1+´C´ + 162 + ´digo de Barras: ´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27972     ;
  Texto := Texto + 27+´G´+0+´UPC-A,UPC-E,JAN8(EAN) COD:39,93,´;
  Texto := Texto + 1310       ;
  Texto := Texto + 27970     ;
  Texto := Texto + ´128,ITF´    ;
  Texto := Texto + 010        ;

  Texto := Texto + ´================================´;
  Texto := Texto + 271004;

  StrMens   := texto;
  WriteFile ( hCom,PChar(StrMens)^,Length(StrMens), BytesEscritos, nil);

end;

//************************************************************************************//



//*********************************//
//   Procedimento para fechar      //
//   a comicação com a porta       //
//*********************************//
procedure TForm1.Image13Click(Sender: TObject);
begin
  CloseHandle(hCom); //Fecha a porta serial.
  cbxPorta.Clear;
  cbxVelocidade.Text := ´´;
end;
//************Fim*****************//




//***********************************//
//   Ao clicar na Imagem, dispara    //
//   o evento para capturar as portas//
//   instaladas no sistema           // 
//***********************************//

procedure TForm1.Image9Click(Sender: TObject);
begin
  MostraPortasCom();
end;
//**************Fim******************//



procedure TForm1.Label1Click(Sender: TObject);
begin
  Application.Terminate
end;

//******************************************//
// Método que captura as portas do registro //
// do windows e lista em um ComboBox        //
//******************************************//

procedure TForm1.MostraPortasCom();
var
  Registro: TRegistry;  //Para trabalhar com os Registros do windows.
  Lista: Tstrings;
  indice: Integer;      //Para incrementar.
begin
  Registro := TRegistry.Create;              //Cria e aloca espaço na memória para o objeto.
  try
    Registro.RootKey := HKEY_LOCAL_MACHINE;  //Define chave raiz.
    Registro.OpenKey(´hardware\devicemap\serialcomm´, False); //Abre a chave.
    Lista := TstringList.Create;
    try
      //Obtém uma string contendo todos os nomes de valores associados com a chave atual.
      Registro.GetValueNames(Lista);
      //Pega nos nomes das portas.
      for indice := 0 to Lista.Count - 1 do //Count é a quantidade de portas existentes.
        cbxPorta.Items.Add(Registro.ReadString( Lista.Strings[indice] ));

     //Adciona os nomes das porta no ComboBox1.
     if cbxPorta.Items.Count > 0 then
        cbxPorta.ItemIndex := 0; //Para exibir o nome da porta.
    finally
      Lista.Free;
    end;
    Registro.CloseKey;
  finally
    Registro.Free;
  end;
end;
//*****************Fim**********************//



//******************************************//
//     Abre conexão com a porta serial      //     
//     especificada no parâmetro            //
//******************************************//
function AbrirPorta(NomePorta:String):boolean;
begin
  hCom := CreateFile(
                     PChar(NomePorta),
                     GENERIC_READ or GENERIC_WRITE,
                     0,                              //Dispositivos COM abertos com acesso exclusivo.
                     nil,                            //Sem atributos de segurança.
                     OPEN_EXISTING,                  //deve usar OPEN_EXISTING
                     0,                              //Entrada e saída sem ovelap.
                     0                               //Deve ser NULL para COM.
                    );
 if(hCom = INVALID_HANDLE_VALUE) then                //Se houve algum erro ao abrir a porta.
   result := false
 else
   result := true;
end;
//*****************Fim**********************//



//******************************************//
//            DEFINE TIMEOUTs               //
//******************************************//

Function ConfiguraTimeOuts:boolean;
begin
  if not GetCommTimeouts(hCom, CommTimeouts) then
    result := false;

  CommTimeouts.ReadIntervalTimeout         := 2;
  CommTimeouts.ReadTotalTimeoutMultiplier  := 0;
  CommTimeouts.ReadTotalTimeoutConstant    := 2;
  CommTimeouts.WriteTotalTimeoutMultiplier := 5;
  CommTimeouts.WriteTotalTimeoutConstant   := 5;

  if not SetCommTimeouts(hCom, CommTimeouts) then
    result := false
  else
    result := true;
end;
//*****************Fim**********************//


//******************************************//
//           CONFIGURA PORTA SERIAL.        //
//******************************************//


Function ConfiguraControle(br: String):boolean;
begin
  if not GetCommState(hCom, dcb) then
    result := false;

  if BR = ´9600´   then  dcb.BaudRate := CBR_9600;     //define velocidade em bps.
  if BR = ´19200´  then  dcb.BaudRate := CBR_19200;    //define velocidade em bps.
  if BR = ´57600´  then  dcb.BaudRate := CBR_57600;    //define velocidade em bps.
  if BR = ´115200´ then  dcb.BaudRate := CBR_115200;   //define velocidade em bps.

  dcb.ByteSize     := 8;                               //define bits de dados.
  dcb.Parity       := NOPARITY;                        //define paridade
  dcb.StopBits     := ONESTOPBIT;                      //define stop bit.

  if not SetCommState(hCom, dcb) then
    result := false
  else
    result := true;
end;
//*****************Fim**********************//


end.


Basicamente o que eu estou te mandando é o que esse componente que você está usando fazer dentro da dll.
Essa parte de Velocidade em bps eu acredito que tenha como jampear na impressora na que eu usei era assim ai você diz no sistema a mesma velocidade

Espero ter ajudado, e não confundido mais.

vlw.


GOSTEI 0
N_informatica

N_informatica

11/04/2007

Amigão fiquei com algumas duvidas, porem tenho certeza de que isso pra vc é simples.

Fiz algumas modificações em cima do código que vc postou aqui no forum e estou com um problema na função AbrirPorta a qual no meu código troquei o nome para AbrePorta.

unit fMain;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, ShellAPI, Registry, IniFiles;

function AbrePorta (NomePorta, br : string) : Boolean; stdcall;
function FechaPorta : Boolean; stdcall;

const
LEN_BUFFER = 100; //Tamanho dos Buffers de Dados;
BIT0 = 1;
BIT1 = 2;
BIT2 = 4;
BIT3 = 8;
BIT4 = 16;
BIT5 = 32;
BIT6 = 64;
BIT7 = 128;

var
hCom : THANDLE; //Handle da Porta Serial (API).
dcb : TDCB; //Estrutura DCB (API).
CommTimeouts : TCOMMTIMEOUTS; //Estrutura TCOMMTIMEOUTS (API).

BytesEscritos : DWORD;
BytesLidos : DWORD;
BufferRecebe : Array [0..LEN_BUFFER] of char; //Define o buffer.
GLB_Conectado : Boolean; //Indica se a porta já está aberta.
GLBEnviaDados : bool; //Para habilitar/desabilitar o envio de dados pela serial.
StrComandos : AnsiString;

implementation

//*********************************************//
// Abre conexão com a porta serial //
// na velocidade especificada no parâmetro //
//*********************************************//

function AbrePorta(NomePorta, br:String):boolean;
begin
hCom := CreateFile(
PChar(NomePorta),
GENERIC_READ or GENERIC_WRITE,
0, //Dispositivos COM abertos com acesso exclusivo.
nil, //Sem atributos de segurança.
OPEN_EXISTING, //deve usar OPEN_EXISTING
0, //Entrada e saída sem ovelap.
0 //Deve ser NULL para COM.
);
if(hCom = INVALID_HANDLE_VALUE) then //Se houve algum erro ao abrir a porta.
result := false
else
begin
if not GetCommState(hCom, dcb) then
result := false;

if BR = ´9600´ then dcb.BaudRate := CBR_9600; //define velocidade em bps.
if BR = ´19200´ then dcb.BaudRate := CBR_19200; //define velocidade em bps.
if BR = ´57600´ then dcb.BaudRate := CBR_57600; //define velocidade em bps.
if BR = ´115200´ then dcb.BaudRate := CBR_115200; //define velocidade em bps.

dcb.ByteSize := 8; //define bits de dados.
dcb.Parity := NOPARITY; //define paridade
dcb.StopBits := ONESTOPBIT; //define stop bit.

if not SetCommState(hCom, dcb) then
result := false
else
begin
if not GetCommTimeouts(hCom, CommTimeouts) then
result := false;

CommTimeouts.ReadIntervalTimeout := 2;
CommTimeouts.ReadTotalTimeoutMultiplier := 0;
CommTimeouts.ReadTotalTimeoutConstant := 2;
CommTimeouts.WriteTotalTimeoutMultiplier := 5;
CommTimeouts.WriteTotalTimeoutConstant := 5;

if not SetCommTimeouts(hCom, CommTimeouts) then
result := false
else
result := true;
end;
end;
end;

//*****************Fim**********************//

//*********************************************//
// Fecha porta serial e encerra comunicação //
//*********************************************//

function FechaPorta : Boolean;
begin
try
CloseHandle(hCom); //Fecha Porta Serial.
Result := True;
except
Result := False;
end;
end;

//*****************Fim**********************//

end.

Esta Unit faz parte da DLL abaixo

library ComSerial;

{ Important note about DLL memory management: ShareMem must be the
first unit in your library´s USES clause AND your project´s (select
Project-View Source) USES clause if your DLL exports any procedures or
functions that pass strings as parameters or function results. This
applies to all strings passed to and from your DLL--even those that
are nested in records and classes. ShareMem is the interface unit to
the BORLNDMM.DLL shared memory manager, which must be deployed along
with your DLL. To avoid using BORLNDMM.DLL, pass string information
using PChar or ShortString parameters. }

uses
SysUtils,
Classes,
fMain in ´fMain.pas´;

{$R *.res}

exports
AbrePorta,
FechaPorta;

begin
end.

Amigo o problema está na função AbrePorta, o hCom esta sendo = INVALID_HANDLE_VALUE e ai ela da o seguinte erro:

Exception EInvalidPointer in module ComSerial.dll at 000026F4

Caso vc me permita posso enviar por e-mail os projetos da DLL e o do programa que chama a DLL.

Obrigado

Tadeu Rodrigues de Oliveira.
Números Informatica.


GOSTEI 0
POSTAR