Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-02-2016
xangiesaurx xangiesaurx is offline
Miembro
NULL
 
Registrado: feb 2016
Posts: 57
Poder: 9
xangiesaurx Va por buen camino
InterlockedExchange en 64 bits

Hola a todos, ya vengo a molestarlos de nuevo, ahora tengo una gran duda, estoy migrando un proyecto de Delphi 2010 a Delphi XE5 (Win64), en el que tengo esta línea de código
Código:
Thread := InterlockedExchange(Integer(FThread), 0);
Pero al parecer el InterlockedExchange no se puede importar a Delphi XE5, alguien sabe de que manera puedo usarlo para que funcione en 64bits?
Gracias
Responder Con Cita
  #2  
Antiguo 18-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Conozco dos "InterlockedExchange"

Una de ellas esta definida en la unidad Windows.Winapi, y es una funcion que depende de una biblioteca externa; si vemos la declaracion:

Código Delphi [-]
function InterlockedExchange; external kernel32 name 'InterlockedExchange';

Por otro lado, la RTL de Delphi incluye una unidad, la System.SyncObjs en donde se define una clase
estatica que implementa la misma funcionalidad pero usando codigo Delphi; es decir, sin dependencias. De hecho, alguna de las funciones son implementadas "dentro del compilador", en lo que comunmente se le llama "magia" o en ingles "compiler magic", o el termino mas tecnico Intrinsic Routines

La clase en cuestion es la TInerlocked

La misma dispone de la funcion estatica Exchange que me imagino que servira para cualquiera de las plataformas que soporta Delphi

Saludos
Responder Con Cita
  #3  
Antiguo 18-02-2016
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Poder: 30
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Toma muy en cuenta la respuesta de AgustinOrtu.

Una pregunta: ¿de qué tipo es FThread?

En caso de ser puntero (u objeto), ten presente que una expresión como Integer(FThread), sólo considerará los cuatro bytes más bajos, ya que Integer es un tipo de dato de 32 bits (aun en plataformas de 64 bits), mientras que un puntero ocupa ocho bytes en sistemas operativos de 64 bits. Es decir, los punteros (los cuales abarcan a las variables objeto también) contienen un valor de 32 o de 64 bits, dependiendo de la plataforma para la que se haya compilado la aplicación.

Un saludo.

Al González.

Última edición por Al González fecha: 18-02-2016 a las 07:36:39.
Responder Con Cita
  #4  
Antiguo 18-02-2016
xangiesaurx xangiesaurx is offline
Miembro
NULL
 
Registrado: feb 2016
Posts: 57
Poder: 9
xangiesaurx Va por buen camino
Muchas gracias por su ayuda, lo eh intentado y me sigue marcando este error:
"[dcc64 Error] BaseClass.pas(9911): E2197 Constant object cannot be passed as var parameter"

Y el código lo eh dejado de la siguiente manera en lo que encuentro como hacerlo funcionar:
Código:
procedure TBCAMThread.Close;
var
  Thread: THandle;
begin
  {$IFDEF WIN32}
    Thread := InterlockedExchange(Integer(FThread), 0);
  {$ELSE}
  {$IFDEF WIN64}


  {$ENDIF}
  {$ENDIF}
  if BOOL(Thread) then
  begin
    WaitForSingleObject(Thread, INFINITE);
    CloseHandle(Thread);
  end;
end;
Responder Con Cita
  #5  
Antiguo 18-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
El problema es que estas usando la funcion incorrectamente

Si vemos la firma de la funcion, tenemos:

Código Delphi [-]
class function Exchange(var Target: Pointer; Value: Pointer): Pointer; overload; static; inline;
class function Exchange(var Target: Integer; Value: Integer): Integer; overload; static; inline;
class function Exchange(var Target: Int64; Value: Int64): Int64; overload; static; inline;
class function Exchange(var Target: TObject; Value: TObject): TObject; overload; static; inline;
class function Exchange(var Target: Double; Value: Double): Double; overload; static; inline;
class function Exchange(var Target: Single; Value: Single): Single; overload; static; inline;
class function Exchangeclass>(var Target: T; Value: T): T; overload; static; inline;

Es importante notar que el primer parametro esta pasado por referencia, de ahi el modificador var

Quiere decir que no se puede enviar por parametro una expresion constante

Un ejemplo de uso correcto de la funcion TInterlocked.Exchange podria ser:

Código Delphi [-]
uses
  System.SyncObjs;

procedure TForm1.Button1Click(Sender: TObject);
var
  A, B, C: Integer;
begin
  A := 1;
  B := 2;
  C := TInterlocked.Exchange(A, B);

  ShowMessageFmt('A = %d, B = %d, C = %d', [A, B, C]);
end;

En donde el cuadro de dialogo imprime el mensaje:

A = 2, B = 1, C = 1

Lo cual es correcto, ya que si revisamos la implementacion de TInerlocked.Exchange, simplemente invoca a otra rutina del compilador, la AtomicExchange, donde la documentación explica:

Cita:
Writes the given value to the target and returns the previous value of the target.
--

Por otro lado tené muy en cuenta lo que comento Al Gonzalez; para responder con precision deberiamos saber el tipo de FThread

Si bien Delphi hace bastante sencilla la transicion de 32 a 64 bits, hay algunos puntos para revisar:

Revisa esta entrada
Responder Con Cita
  #6  
Antiguo 19-02-2016
xangiesaurx xangiesaurx is offline
Miembro
NULL
 
Registrado: feb 2016
Posts: 57
Poder: 9
xangiesaurx Va por buen camino
AgustinOrtu, gracias por tu ayuda, parece que ya quedo solucionado, el código quedo de la siguiente manera
Código:
                {$IFDEF WIN32}
    			Thread := InterlockedExchange(Integer(FThread), 0);
  		{$ELSE}
  		{$IFDEF WIN64}
    			Thread := TInterlocked.Exchange(Int64(FThread), 0);
  		{$ENDIF}
  		{$ENDIF}
Lo hice de esta manera ya que me pidieron que tuviera el conditional compilation

Última edición por xangiesaurx fecha: 19-02-2016 a las 02:26:15.
Responder Con Cita
  #7  
Antiguo 19-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
Sólo una cosa más para puntualizar

Se recomienda el uso del tipo NativeInt para los casos en los que, como este, hay que lidiar con el diferente tamaño de los punteros

El tipo NativeInt, esta definido como un entero de 32 bits para el compilador de 32 bits, y como entero de 64 bits para el compilador de 64 bits

Es una manera de escribir código compatible a través de todas las plataformas, asegurando compatibilidad hacia adelante y atrás
Responder Con Cita
  #8  
Antiguo 20-02-2016
xangiesaurx xangiesaurx is offline
Miembro
NULL
 
Registrado: feb 2016
Posts: 57
Poder: 9
xangiesaurx Va por buen camino
Si, muchas gracias, se me había pasado lo del NativeInt :P Pero ya esta implementado

Ahora tengo otra duda (ya se que soy algo latosa en esto), pero me acabo de encontrar parte de código ensamblador, pero a lo que eh leido, ya no es compatible con XE5, existe alguna forma de lograr esta compatibilidad?
(Aquí dejo el código en cuestion)

Código Delphi [-]
function FastCpySSE(const D:Pointer; const S:Pointer; const count:dword):integer;
var dwNumElements, dwNumPacksWORD;
begin
 dwNumElements := count div sizeof(integer);
 // not really using it, just for debuging. it keeps number of looping.
 // it also means number of packed data.
 dwNumPacks := dwNumElements div (128 div (sizeof(integer)*8));

 asm
  // remember for cleanup
  pusha;
@@begin:
  // init counter to SizeInBytes
  mov  ecx,count
  // get destination pointer
  mov  edi,D
  // get source pointer
  mov  esi,S
@@begina:
  // check if counter is 0, yes end loop.
  cmp  ecx,0
  jz  @@end
@@body:
  // calculate offset
  mov  ebx,count
  sub  ebx,ecx
  // copy source's content to 128 bits registers
  movdqa xmm1,[esi+ebx]
  // copy 128 bits registers to destination
  movdqa [edi+ebx],xmm1;

@@bodya:
  // we've done "1 packed == 4 * sizeof(int)" already.
  sub  ecx,16;
  jmp  @@begina
@@end:
  // cleanup
  popa;
end;

 result := 0;;
end;
Gracias por toda su ayuda y de nuevo una disculpa por las molestias

Última edición por Casimiro Notevi fecha: 20-02-2016 a las 00:45:45.
Responder Con Cita
  #9  
Antiguo 20-02-2016
Avatar de AgustinOrtu
[AgustinOrtu] AgustinOrtu is offline
Miembro Premium
NULL
 
Registrado: ago 2013
Ubicación: Argentina
Posts: 1.858
Poder: 15
AgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en brutoAgustinOrtu Es un diamante en bruto
xangiesaurx

Realmente no domino ASM, pero de todos modos deberías iniciar una consulta nueva y no mezclar en un mismo hilo varias preguntas; asi lo dice la guía de estilo
Responder Con Cita
  #10  
Antiguo 20-02-2016
xangiesaurx xangiesaurx is offline
Miembro
NULL
 
Registrado: feb 2016
Posts: 57
Poder: 9
xangiesaurx Va por buen camino
De acuerdo, entonces este tema se puede dar por cerrado.
Abriré uno nuevo con referencia a ASM y XE5, muchas gracias por toda la ayuda
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Instalar componentes de 32 bits en una PC de win7 a 64 bits uper Windows 10 29-01-2016 18:08:30
compilar programas 32 bits con lazarus 64 bits anubis Lazarus, FreePascal, Kylix, etc. 3 30-10-2013 18:08:44
Pasar varible de 16 bits a dos de 8 bits bactering C++ Builder 7 04-11-2010 04:44:33
Como ejecutar aplicativos dbExpress de 32 bits en 64 bits rolandoj Conexión con bases de datos 0 30-07-2010 19:39:07
Aplicaciones de 32 bits en Windows de 64 bits Gabo Debates 9 25-09-2008 20:49:32


La franja horaria es GMT +2. Ahora son las 15:24:58.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi