Erro em DLL para impressão direta p/porta serial
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.
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
Curtidas 0
Respostas
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
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
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
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
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
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.
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