Jump to content


Photo

Uso de Safecall, stdCcall y otras cosas de esas......


  • Please log in to reply
7 replies to this topic

#1 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2137 posts

Posted 28 November 2009 - 03:45 PM

Compañeros, tratando de resolver un problema en datasnap, veo que depronto la solución para por la utilización correcta de  Safecall, Stdcall y demás objetos relacionados.

Quisiera que algún compañero me ilustrara sobre su uso, algo así  como saber: cuando, donde, cómo se usan y que hacen.

De antemano gracias por su colaboración y tiempo.
  • 0

#2 seoane

seoane

    Advanced Member

  • Administrador
  • 1259 posts
  • LocationEspaña

Posted 28 November 2009 - 04:36 PM

La respuesta la tienes en la ayuda de Delphi:

Calling conventions determine the order in which parameters are passed to the routine. They also affect the removal of parameters from the stack, the use of registers for passing parameters, and error and exception handling. The default calling convention is register.

The register and pascal conventions pass parameters from left to right; that is, the left most parameter is evaluated and passed first and the rightmost parameter is evaluated and passed last. The cdecl, stdcall, and safecall conventions pass parameters from right to left.
For all conventions except cdecl, the procedure or function removes parameters from the stack upon returning. With the cdecl convention, the caller removes parameters from the stack when the call returns.
The register convention uses up to three CPU registers to pass parameters, while the other conventions pass all parameters on the stack.
The safecall convention implements exception 'firewalls.' On Win32, this implements interprocess COM error notification.


Resumiendo, estas directivas indican como se deben de pasar los parámetros de una función, el orden en que se pasan y quien es el encargado del limpiarlos.

La mayoría de las funciones de la API de windows utilizan stdcall, en C se suele usar cdecl y en delphi Register, son solo diferentes métodos de hacer lo mismo, pero es muy importe que cuando llames a una función uses el mismo método que quien la creo, de lo contrario no funcionara, o lo que es peor puede provocar errores en la pila con resultados imprevisibles
  • 0

#3 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4111 posts
  • LocationMadrid - España

Posted 28 November 2009 - 05:17 PM

En C existe una modifucador especial, __declspec(naked). No se si en delphi existirá algo parecido, supongo que si.



cpp
  1. __declspec(naked) Tipo_devuelto MiFuncion(Tipo Param)
  2. {
  3.   //.......
  4. }



__declspec(naked) consigue que la función que escribamos no tenga añadidura alguna por parte del compilador, así, para realizar funciones de asm puro, estaremos seguros de que el compilador no nos añade nada, es decir, no reserva pila ni prepara retorno alguno. Todo eso lo haremos nosotros dejándonos todo el control.

Muy útil en ciertos casos.

¿Delphi tiene alguna equivalencia?  :^)

Saludos.
  • 0

#4 seoane

seoane

    Advanced Member

  • Administrador
  • 1259 posts
  • LocationEspaña

Posted 28 November 2009 - 05:41 PM

¿Delphi tiene alguna equivalencia?  :^)


Pues no se si existe una equivalencia, pero puedes echarle un vistazo a "Assembly Procedures and Functions" en la ayuda.
  • 0

#5 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2137 posts

Posted 28 November 2009 - 06:01 PM

Gracias a Escafandra y Seoane.

Sería posible un ejemplito muy pequeñito de su uso.

Muchas gracias.
  • 0

#6 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4111 posts
  • LocationMadrid - España

Posted 28 November 2009 - 06:04 PM


¿Delphi tiene alguna equivalencia?  :^)


Pues no se si existe una equivalencia, pero puedes echarle un vistazo a "Assembly Procedures and Functions" en la ayuda.


He seguido tu recomendación. Veo que se parece en algo, pero en ese caso el compilador si introduce algo de código...

Saludos.
  • 0

#7 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4111 posts
  • LocationMadrid - España

Posted 28 November 2009 - 06:59 PM

Los mas importantes son stdcall y cdecl. Las API de Win32 son todas stdcall.

En C un ejemplo sería así:


cpp
  1. _stdcall int MiFuncion(int i);



En delphi tendríamos esta equivalencia:


delphi
  1. function MiFuncion(i, integerl): int; _stdcall;



El C utiliza como tipo estándar el cdecl que permite un número indefinido de argumentos para una función. Si vemos el código en asm veremos que los argumentos se pasan de derecha a izquierda, apilados en la pila. Normalmente el retorno es en EAX y no restaura la pila, eso lo debe hacer la función que hace la llamada.

Generalmente no hace falta poner cdecl porque es implicito, a no ser que se configure el compilador de otra forma por defecto.

Las APIs de Win32 son stdcall. Implica que los parámetros se pasan de derecha a izquierda en la pila, se retorna en EAX pero en este caso la función llamada debe restaurar la pila.

delphi usa como estandar fastcall que pasa los primeros parámetros de izquierda a derecha en EAX, EDX, ECX y el resto en la pila.

Como te comentó seoane es importante llamar a una función con su convención de llamada de su creador, en caso contrario, probablemente, tendremos un cuelgue de la aplicación.

Normalmente no nos tenemos que preocupar de estas cosas a menos que queramos importar funciones de librerías, entonces tendremos que conocer la convención usada. Colocando el modificador adecuado el compilador hace el resto.

Aquí puedes leer mas.

Saludos.

  • 0

#8 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2137 posts

Posted 28 November 2009 - 11:30 PM

Gracias escafandra, ya comentaré resultados.
  • 0




IP.Board spam blocked by CleanTalk.