Ir al contenido


Foto

Error en parámetro por referencia en componente ActiveX

ActiveX ActiveX Delphi

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

#1 Manuel Peña

Manuel Peña

    Newbie

  • Miembros
  • Pip
  • 5 mensajes

Escrito 19 septiembre 2018 - 12:29

Amigos del Foro,

 

Actualmente estoy usando un componente ActiveX y tengo problemas con el parámetro por referencia de la función de este componente.

 

la definición de la función es: 

 

HRESULT ReadInformation([in] BSTR* szCard, [in] int iTimeChip, [in] int iTimeMag, [in] int iType, [in] BSTR messMag, [out, retval] int *rc)

 

Definiendo un procedimiento de forma normal que haga uso de la función me salia el siguiente error:  "Access violations at address 1381O7AO in module *.DLL. Write of address 00000000"


delphi
  1. procedure TForm2.btnConInfClick(Sender: TObject);
  2. var
  3. ....
  4. CardInformation : WideString;
  5. begin
  6. try
  7. ...
  8. ReadCardResult:= MyCompActX.ReadInformation(CardInformation, 20, 20, 1, 'INGRESE NUM...');
  9. if Trim(CardInformation) <> '' then
  10. ShowMessage(CardInformation);
  11. finally
  12. MyCompActX.Free;
  13. end;
  14. end;

Luego haciendo una investigación y sugerencias de unos amigos me indicaron que tenia que hacer uso de punteros con memoria dinámica y llegue a la siguiente solución:


delphi
  1. procedure TForm2.btnConInfClick(Sender: TObject);
  2. var
  3. CardInformation : ^WideString;
  4. CardInformation2 : WideString;
  5. begin
  6. try
  7. ...
  8. try
  9. GetMem(CardInformation, 255 * 2);
  10. ReadCardResult:= MyCompActX.ReadInformation(CardInformation^, 20, 20, 1, 'INGRESE NUM...');
  11. CardInformation2 := PWideChar(CardInformation^);
  12. finally
  13. FreeMem(CardInformation);
  14. end;
  15. if Trim(CardInformation2) <> '' then
  16. ShowMessage(CardInformation2);
  17. finally
  18. MyCompActX.Free;
  19. end;
  20. end;

El problema que tengo y las preguntas son las siguiente:

 

1. La solución me funciona en una versión reciente de Delphi( Delphi Tokyo), cuando intento hacer lo mismo en una versión Delphi 6 me esta generando un error al castear el puntero ( CardInformation2 := PWideChar(CardInformation^); ),  ERROR:  "invalid pointer operation "  pueden ayudarme a identificar donde esta el problema?

2. Capaz con la experiencia de un amigo del foro, capaz haya otra forma de obtener el resultado de la función? o capaz haya otra forma de como consumir la función con memoria dinámica? capaz la forma de castear el puntero en Delphi 6 no lo soporta?

 

Muchas gracias por sus comentarios y espero me puedan ayudar con sus sugerencias.  :ap:

 

Saludos a todos los amigos del Foro.

 

 


  • 0

#2 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.419 mensajes
  • LocationRepública Dominicana

Escrito 19 septiembre 2018 - 05:00

A partir de Delphi 2007 hacia atrás (D2006,D8,D7,D6,D5) en tu caso sería utilizar PChar, y a partir de Delphi 2007 hacia más reciente PWideChar, aunque viene siendo lo mismo que PChar, sólo que en el primer caso PChar = PAnsiChar y en el segundo PChar = PWideChar.

 

Saludos.


  • 0

#3 Manuel Peña

Manuel Peña

    Newbie

  • Miembros
  • Pip
  • 5 mensajes

Escrito 19 septiembre 2018 - 05:49

Gracias por tu respuesta amigo enecumene

 

Lo que pasa cuando importo el componente ActiveX desde D6 esta es la definición que me genera:

 

function  ReadInformation(var Param1: WideString; Param2: SYSINT; Param3: SYSINT; Param4: SYSINT; const Param5: WideString): SYSINT; safecall;
 
por ello que utilizo los tipos WideString. 
 
Al momento que obtengo el valor de memoria (CardInformation2 := PWideChar(CardInformation^)) parece que el puntero hace referencia a variable: CardInformation2 ya que me da error al momento de liberar el puntero ( FreeMem(CardInformation) ) el error que sale es: "invalid pointer operation"
 
he intentado usar la variable  CardInformation2 y me sale erro de "Access Violation"
 
Todo esto me ocurre en D6. ya que en las nuevas versiones es transparente y la liberación de la memoria no muestra error.
 
Se que D6 maneja mas PCHAR, tienes alguna idea de como podría ser la definición en D6 para evitar errores de puntero y/o memoria.
 
muchas gracias.

  • 0

#4 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 21 septiembre 2018 - 12:22

Alparecer partes de esta definición:


php
  1. HRESULT ReadInformation([in] BSTR* szCard, [in] int iTimeChip, [in] int iTimeMag, [in] int iType, [in] BSTR messMag, [out, retval] int *rc) 

Que se adapta a delphi de esta forma: 


delphi
  1. function  ReadInformation(var Param1: WideString; Param2: SYSINT; Param3: SYSINT; Param4: SYSINT; const Param5: WideString): SYSINT; safecall;

 
 Sin poder probar ningún código, creo interpretar que BSTR son cadenas estilo Visual Basic y que la función devolverá en szCard una cadena que habrá que liberar después de su uso, pero no asignarle memoria alguna antes de entrar en la función ReadInformation. 
 


delphi
  1. var
  2. CardInformation : ^WideString;
  3. CardInformation2 : WideString;
  4. begin
  5. ReadInformation(CardInformation^, 20, 20, 1, 'INGRESE NUM...');
  6. CardInformation2 := CardInformation^;
  7. SysFreeString(CardInformation);
  8. end;

Independientemente de como se libere CardInformation, la copia debería debería hecerse de forma que se asigne el valor de CardInformation a CardInformation2:


delphi
  1. CardInformation2 := CardInformation^;

Sin poder probar el código, no puedo afinar mas en los posibles errores que puedan aparecer tras el uso de la función importada.

 

 

 

Saludos.


  • 1

#5 Manuel Peña

Manuel Peña

    Newbie

  • Miembros
  • Pip
  • 5 mensajes

Escrito 24 septiembre 2018 - 08:13

Hola Escafandra,

No me funciona así como me mencionas ya que me sale error de compilación. mensajes anteriores lo indico.

Mira actualmente ese tema no lo he podido resolver de a primeras ya que el problema parte por la versión de delphi y el SO.

Yo como menciono lineas atrás con una versión delphi mas actual(Tokyo) no genera ese error. el problema es con la versión D6. como esa versión es bastante antigua parece que maneja de otra manera el tema de punteros y/o memoria en windows 10. actualmente del mismo componente se usa de forma similar pero la definición del parámetro como "OUT". pero con la función que generaba el error la crearon con "IN".

En general hice el intento de muchas formas y no pude resolver el error. después de varios días de investigación se solicito que cambien la definición de la función del componente.

Gracias a todos los amigos del foro por sus comentarios.

Saludos.


  • 0





Etiquetado también con una o más de estas palabras: ActiveX, ActiveX Delphi

IP.Board spam blocked by CleanTalk.