Ir al contenido


Foto

Una DLL que se me esta haciendo imposible terminar


  • Por favor identifícate para responder
3 respuestas en este tema

#1 FGarcia

FGarcia

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 687 mensajes
  • LocationMéxico

Escrito 26 noviembre 2008 - 08:52

Pues eso solamente.... :

Tengo la necesidad de encapsular un componente de terceros (TComPort) dentro de una DLL para que pueda ser usado desde otra aplicacion (VB.net), NO es solo el componente serial lo que me interesa pues en C# y VB.net existe una libreria (¡al fin lo dije sin esperar un regaño!) para tal fin, son las funciones añadidas las que realmente daran valor a la dll. Por el momento me he centrado en la funcion del puerto de comunicaciones y no he podido pasar de ahi. Con el codigo que actualmente tengo abro, cierro, cambio ajustes del puerto serie, mi problema radica en que los procedimientos de Salvar y guardar los cambios a la configuracion no me funcionan, me genera un error. Dichos datos de configuracion se guardan a discrecion en un archivo INI o en el registro, yo he seleccionado INI por la facilidad de hacer cambios sin necesidad de ser administrador. Pues bien, el archivo INI SI se crea pero el error que me genera es que no ha podido escribir la aplicacion nada en el.

Esta es mi DLL:



delphi
  1. library comScale;
  2.  
  3. { Important note about DLL memory management: ShareMem must be the
  4.   first unit in your library's USES clause AND your project's (select
  5.   Project-View Source) USES clause if your DLL exports any procedures or
  6.   functions that pass strings as parameters or function results. This
  7.   applies to all strings passed to and from your DLL--even those that
  8.   are nested in records and classes. ShareMem is the interface unit to
  9.   the BORLNDMM.DLL shared memory manager, which must be deployed along
  10.   with your DLL. To avoid using BORLNDMM.DLL, pass string information
  11.   using PChar or ShortString parameters. }
  12.  
  13. uses
  14.   SysUtils,
  15.   Classes,
  16.   Forms,
  17.   Dialogs,
  18.   CPort;
  19.  
  20. {$R *.res}
  21.  
  22. var
  23.   PuertoS: TComPort;
  24.   num: integer;
  25.  
  26. function CrearPuerto: boolean; stdCall;
  27. begin
  28.   Result := True;
  29.   try
  30.     PuertoS := TComPort.Create(Application);
  31.     PuertoS.TriggersOnRxChar := True;
  32.     PuertoS.EventThreadPriority := tpNormal;
  33.     PuertoS.Port := 'Com1';
  34.     PuertoS.BaudRate := br9600;
  35.     PuertoS.Parity.Bits  := prNone;
  36.     PuertoS.StopBits := sbOneStopBit;
  37.     PuertoS.DataBits := dbEight;
  38.     PuertoS.Events := [evRxChar, evTxEmpty, evRxFlag, evRing, evBreak, evCTS, evDSR, evError, evRLSD, evRx80Full];
  39.     PuertoS.StoredProps := [spBasic];
  40.     PuertoS.FlowControl.OutCTSFlow := False;
  41.     PuertoS.FlowControl.OutDSRFlow := False;
  42.     PuertoS.FlowControl.ControlDTR := dtrDisable;   
  43.     PuertoS.FlowControl.ControlRTS := rtsDisable;
  44.     PuertoS.FlowControl.XonXoffOut := False;
  45.     PuertoS.FlowControl.XonXoffIn := False;
  46.   except
  47.     Result := false;
  48.     Showmessage('Imposible crear el puerto de comunicaciones');
  49.   end;
  50. end;
  51.  
  52. procedure DestruirPuerto;  stdCall;
  53. begin
  54.   PuertoS.Free ;   
  55. end;
  56.  
  57. function AbrirPuerto : boolean; stdCall;
  58. begin
  59.   Result := True;
  60.   try
  61.     PuertoS.Open ;
  62.   except
  63.     Result := false;
  64.     ShowMessage('Imposible abrir el puerto de comunicaciones');
  65.   end;
  66. end;
  67.  
  68. function CerrarPuerto : boolean;  stdCall;
  69. begin
  70.   result := true;
  71.   try
  72.     If PuertoS.Connected then
  73.       PuertoS.Close ;
  74.   except
  75.     result := false;
  76.   end;
  77. end;
  78.  
  79. procedure GuardarCFG(archivo: PChar); stdCall;
  80. begin
  81.   PuertoS.StoreSettings(stIniFile, strPas(Archivo));
  82. end;
  83.  
  84. procedure CargarCFG(archivo: PChar); stdCall;
  85. begin
  86.   PuertoS.LoadSettings(stIniFile, strPas(Archivo));
  87. end;
  88.  
  89. procedure MuestraSetup; stdCall;
  90. begin
  91.   PuertoS.ShowSetupDialog ;
  92. end;
  93.  
  94. function AjustesActuales : PChar; stdCall;
  95. begin
  96.   Result := PChar(PuertoS.Port + ',' + BaudRatetoStr(PuertoS.BaudRate) + ',' +
  97.                                 DataBitsToStr(PuertoS.DataBits) + ',' +
  98.                                 ParityToStr(PuertoS.Parity.Bits) + ',' +
  99.                                 StopBitstoStr(PuertoS.StopBits));
  100. end;
  101.  
  102. exports
  103.     CrearPuerto,
  104.     AbrirPuerto,
  105.     CerrarPuerto,
  106.     GuardarCFG,
  107.     CargarCFG,
  108.     MuestraSetup,
  109.     AjustesActuales;
  110.  
  111. begin
  112. end.



Este es el ejemplo de uso (1 formulario con un statusbar y un panel que contiene 7 botones ):



delphi
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, ComCtrls, StdCtrls, ExtCtrls, IniFiles;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     Panel1: TPanel;
  12.     btnCrear: TButton;
  13.     btnAbrir: TButton;
  14.     btnCerrar: TButton;
  15.     btnCfg: TButton;
  16.     btnStoreCFG: TButton;
  17.     btnLoadCFG: TButton;
  18.     StatusBar1: TStatusBar;
  19.     btnMuestra: TButton;
  20.     procedure btnCrearClick(Sender: TObject);
  21.     procedure btnAbrirClick(Sender: TObject);
  22.     procedure btnCerrarClick(Sender: TObject);
  23.     procedure btnCfgClick(Sender: TObject);
  24.     procedure btnMuestraClick(Sender: TObject);
  25.     procedure btnStoreCFGClick(Sender: TObject);
  26.     procedure btnLoadCFGClick(Sender: TObject);
  27.   private
  28.     { Private declarations }
  29.   public
  30.     { Public declarations }
  31.   end;
  32.  
  33. var
  34.   Form1: TForm1;
  35.  
  36. function CrearPuerto: boolean; stdcall; external 'ComScale.dll';
  37. procedure DestruyePuerto; stdcall; external 'ComScale.dll';
  38. function AbrirPuerto: boolean; stdcall; external 'ComScale.dll';
  39. function CerrarPuerto: boolean; stdcall; external 'ComScale.dll';
  40. procedure MuestraSetup; stdcall; external 'ComScale.dll';
  41. procedure CargarCFG(archivo: PChar); stdcall; external 'ComScale.dll';
  42. procedure GuardarCFG(archivo: PChar); stdcall; external 'ComScale.dll';
  43. function AjustesActuales: PChar; stdcall; external 'ComScale.dll';
  44.  
  45. implementation
  46.  
  47. {$R *.dfm}
  48.  
  49. procedure TForm1.btnCrearClick(Sender: TObject);
  50. begin
  51.   if CrearPuerto then
  52.     StatusBar1.Panels[0].Text := 'Puerto Creado';
  53. end;
  54.  
  55. procedure TForm1.btnAbrirClick(Sender: TObject);
  56. begin
  57.   if AbrirPuerto then
  58.     StatusBar1.Panels[1].Text := 'Conectado';
  59. end;
  60.  
  61. procedure TForm1.btnCerrarClick(Sender: TObject);
  62. begin
  63.   if CerrarPuerto then
  64.     StatusBar1.Panels[1].Text := 'Desconectado';
  65. end;
  66.  
  67. procedure TForm1.btnCfgClick(Sender: TObject);
  68. begin
  69.   MuestraSetup;
  70. end;
  71.  
  72. procedure TForm1.btnStoreCFGClick(Sender: TObject);
  73. var
  74.   Archivo: string;
  75. begin
  76.   Archivo := ExtractFilePath(ParamStr(0)) + 'CommCfg.ini';
  77.   GuardarCFG(pchar(Archivo));
  78. end;
  79.  
  80. procedure TForm1.btnLoadCFGClick(Sender: TObject);
  81. var
  82.   Archivo: string;
  83. begin
  84.   Archivo := ExtractFilePath(ParamStr(0)) + 'CommCfg.ini';
  85.   CargarCFG(pchar(Archivo));
  86. end;
  87.  
  88. procedure TForm1.btnMuestraClick(Sender: TObject);
  89. begin
  90.   StatusBar1.Panels[2].Text := AjustesActuales;
  91. end;
  92.  
  93.  
  94. end.



Todos los procedimientos me funcionan salvo los de guardar (btnStoreCFGClick) y Cargar (btnLoadCFGClick); aqui debo puntualizar que el de guardar es el unico que he usado pues es el que crea el archivo INI el de cargar no lo he usado pues al no existir el ini no hace nada.

Este es el procedimiento del ComPort para guardar en un INI:



delphi
  1. procedure TCustomComPort.StoreIniFile(IniFile: TIniFile);
  2. begin
  3.   if spBasic in FStoredProps then
  4.   begin
  5.     IniFile.WriteString(Name, 'Port', Port);
  6.     IniFile.WriteString(Name, 'BaudRate', BaudRateToStr(BaudRate));
  7.     if BaudRate = brCustom then
  8.       IniFile.WriteInteger(Name, 'CustomBaudRate', CustomBaudRate);
  9.     IniFile.WriteString(Name, 'StopBits', StopBitsToStr(StopBits));
  10.     IniFile.WriteString(Name, 'DataBits', DataBitsToStr(DataBits));
  11.     IniFile.WriteString(Name, 'Parity', ParityToStr(Parity.Bits));
  12.     IniFile.WriteString(Name, 'FlowControl', FlowControlToStr(FlowControl.FlowControl));
  13.   end;
  14.   if spOthers in FStoredProps then
  15.   begin
  16.     IniFile.WriteString(Name, 'EventChar', CharToStr(EventChar));
  17.     IniFile.WriteString(Name, 'DiscardNull', BoolToStr(DiscardNull));
  18.   end;
  19.   if spParity in FStoredProps then
  20.   begin
  21.     IniFile.WriteString(Name, 'Parity.Check', BoolToStr(Parity.Check));
  22.     IniFile.WriteString(Name, 'Parity.Replace', BoolToStr(Parity.Replace));
  23.     IniFile.WriteString(Name, 'Parity.ReplaceChar', CharToStr(Parity.ReplaceChar));
  24.   end;
  25.   if spBuffer in FStoredProps then
  26.   begin
  27.     IniFile.WriteInteger(Name, 'Buffer.OutputSize', Buffer.OutputSize);
  28.     IniFile.WriteInteger(Name, 'Buffer.InputSize', Buffer.InputSize);
  29.   end;
  30.   if spTimeouts in FStoredProps then
  31.   begin
  32.     IniFile.WriteInteger(Name, 'Timeouts.ReadInterval', Timeouts.ReadInterval);
  33.     IniFile.WriteInteger(Name, 'Timeouts.ReadTotalConstant', Timeouts.ReadTotalConstant);
  34.     IniFile.WriteInteger(Name, 'Timeouts.ReadTotalMultiplier', Timeouts.ReadTotalMultiplier);
  35.     IniFile.WriteInteger(Name, 'Timeouts.WriteTotalConstant', Timeouts.WriteTotalConstant);
  36.     IniFile.WriteInteger(Name, 'Timeouts.WriteTotalMultiplier', Timeouts.WriteTotalMultiplier);
  37.   end;
  38.   if spFlowControl in FStoredProps then
  39.   begin
  40.     IniFile.WriteString(Name, 'FlowControl.ControlRTS', RTSToStr(FlowControl.ControlRTS));
  41.     IniFile.WriteString(Name, 'FlowControl.ControlDTR', DTRToStr(FlowControl.ControlDTR));
  42.     IniFile.WriteString(Name, 'FlowControl.DSRSensitivity', BoolToStr(FlowControl.DSRSensitivity));
  43.     IniFile.WriteString(Name, 'FlowControl.OutCTSFlow', BoolToStr(FlowControl.OutCTSFlow));
  44.     IniFile.WriteString(Name, 'FlowControl.OutDSRFlow', BoolToStr(FlowControl.OutDSRFlow));
  45.     IniFile.WriteString(Name, 'FlowControl.TxContinueOnXoff', BoolToStr(FlowControl.TxContinueOnXoff));
  46.     IniFile.WriteString(Name, 'FlowControl.XonXoffIn', BoolToStr(FlowControl.XonXoffIn));
  47.     IniFile.WriteString(Name, 'FlowControl.XonXoffOut', BoolToStr(FlowControl.XonXoffOut));
  48.     IniFile.WriteString(Name, 'FlowControl.XoffChar', CharToStr(FlowControl.XoffChar));
  49.     IniFile.WriteString(Name, 'FlowControl.XonChar', CharToStr(FlowControl.XonChar));
  50.   end;
  51. end;



Razonando un poco me pregunto si el problema no estara en los IniFile.WriteString que debieran ser convertidos a PChar, pero ahi entonces ¿Como se hace eso?

Se que para muchos al no tener en su PC un puerto serie pues esto les generaria un error pero si pueden cuando menos echarle un ojo...

¡¡Ilustres maestros os imploro ayuda!! ¡¡Dejen un rato de adorar a Baco y regresen al oraculo de Delphos!!
  • 0

#2 eduarcol

eduarcol

    Advanced Member

  • Administrador
  • 4.483 mensajes
  • LocationVenezuela

Escrito 27 noviembre 2008 - 06:53

no se si lo has intentado, pero que valor esta tomando la variable archivo antes de llamar a GuardarArchivo, me refiero a este trozo de codigo:



delphi
  1. procedure TForm1.btnStoreCFGClick(Sender: TObject);
  2. var
  3.   Archivo: string;
  4. begin
  5.   Archivo := ExtractFilePath(ParamStr(0)) + 'CommCfg.ini';
  6.   GuardarCFG(pchar(Archivo));
  7. end;




Se que es algo basico, pero a simple vista no veo el detalle, ahora hay que ir paso a paso y ver como se comportan los valores.
  • 0

#3 seoane

seoane

    Advanced Member

  • Administrador
  • 1.259 mensajes
  • LocationEspaña

Escrito 27 noviembre 2008 - 07:29

¿Te muestra un mensaje de error o simplemente no escribe nada en el ini? Porque si es lo segundo asegurate de que FStoredProps tiene un valor adecuado para cumplir alguno de los if de StoreIniFile


  • 0

#4 FGarcia

FGarcia

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 687 mensajes
  • LocationMéxico

Escrito 27 noviembre 2008 - 11:15

El mensaje de error:

---------------------------
Debugger Exception Notification
---------------------------
Project UsaComScale.exe raised exception class EComPort with message 'Failed to store settings'. Process stopped. Use Step or Run to continue.
---------------------------
OK  Help 
---------------------------


El valor de Archivo:

C:\GLAF_DEV\ComScale_Origen\JUNTAS\CommCFG.ini


CommCFG.ini si se crea, no se escribe nada en el. :| :s :
  • 0




IP.Board spam blocked by CleanTalk.