Definizione dei tipi da altre unità a Delfi
-
23-08-2019 - |
Domanda
Var
A : Array [1..4] of Integer;
B : Array [1..4] of Integer;
Begin
A := B;
non funzionerà come Loren-pechtel detto qui il problema è A e B per me sono in unità diverse. Quindi, c'è un modo per definire una definizione di tipo da uno già esistente in un'altra classe?
Soluzione
Definisci tipo nel blocco di interfaccia di qualche unità e quindi includere tale unità tramite la clausola uses
in altre unità in cui è necessario quel tipo.
unit A;
interface
type
TMyArray = array [1..4] of Integer;
...
Quando è necessario utilizzare TMyArray
in un'altra unità:
unit B;
interface
uses A;
...
var x : TMyArray;
Altri suggerimenti
In alternativa, definire il tipo in una sezione interfaccia dell'unità C e utilizzare questa unità A e B.
tipi di array in Delphi sono un po 'strano. E ' guarda come A e B sono esattamente dello stesso tipo, ma Delphi non ritiene che essi sono la stessa cosa. "Array [1..4] di Integer" appare due volte, in modo da Delphi pensa che ci sono due tipi diversi. Questo è solo una stranezza di Delfi. La maggior parte delle altre lingue, credo, non mi importerebbe. Non è un problema nella pratica; è solo un po 'strano. Forse c'è una buona ragione per questo. Chissà. La soluzione, come gli altri hanno detto, è definire un tipo, che si può mettere in un'unità che può essere utilizzato da altre unità. Mi limito a citare questo numero di tipi di matrice perché può essere si confonde.
Un altro approccio, un po 'vecchia scuola, ma funziona ancora, è quello di utilizzare la parola chiave assoluto di forzare la memoria di uno di sovrapporre l'altro, e rendere l'altro tipo compatibile. Per esempio, in unità di un Diciamo che avere il seguente:
TYPE
TArrayA = Array[1..4] of integer;
: poi in unità B, si ha la seguente:
TYPE
TArrayB = Array[1..4] of integer;
Per la compatibilità, è possibile effettuare le seguenti operazioni:
VAR
InstanceA : TArrayA;
InstanceB : TArrayB;
InstanceBasA : TArrayA ABSOLUTE InstanceB;
Quello che fa è creare una variabile "InstanceBasA" di tipo Arraya che si sovrappone lo stesso spazio di memoria, come la variabile "InstanceB". Questo consente di eseguire il seguente comando:
InstanceA := InstanceBasA;
Un altro metodo per spostamento dei dati da variabileA a variabileB è quello di utilizzare il comando SPOSTA. Ad esempio, per passare da Arraya a ArrayB è possibile effettuare le seguenti operazioni:
var
ArrayA : array[1..4] of Integer;
ArrayB : Array[1..4] of Integer;
begin
FillChar(ArrayB[1],SizeOf(ArrayB),#0);
ArrayA[1] := 1234;
ArrayA[2] := 3456;
ArrayA[3] := 7890;
ArrayA[4] := 9876;
// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );
Assert( ArrayA[4] = ArrayB[4], 'ArrayA[4] <> ArrayB[4]');
end;
Questo funziona dal fatto che la matrice è spiegate in modo lineare, in modo che il copiando i byte a partire dalla prima posizione di matrice, per la lunghezza della matrice.
È possibile forzare il compilatore di assumere essi sono dello stesso tipo da loro typecasting:
type
TIntArray = array[1..4] of integer;
begin
Assert(SizeOf(ArrayA) = SizeOf(TIntArray));
Assert(SizeOf(ArrayB) = SizeOf(TIntArray));
TIntArray(ArrayA) := TIntArray(ArrayB);
Ma si deve fare in modo che sia in realtà sono array [1..4] del altrimenti si sovrascriverà po 'di memoria. È per questo che ho aggiunto le due affermazioni.
Basta usare le unità in unità dopo interfaccia e prima del applicazione ... !!!!
Mai, mai, MAI usare il codice come questo:
// This is where the move from ArrayA to ArrayB happens.
Move( ArrayA[1], ArrayB[1], SizeOf(ArrayA) );
Dov'è la falla? Si sta utilizzando la dimensione SOURCE per ottenere il numero di byte da spostare, non la dimensione DESTINAZIONE !!! Se SizeOf (A)> SizeOf (B) si dispone di un buffer overflow e si sta sovrascrivendo la memoria. Se siete fortuna si ottiene un AV, se non sei di avere una vulnerabilità sfruttabile. E 'molto meglio usare sempre la dimensione di destinazione, anche se in questo modo si può finire memoria lettura non si deve se la dimensione (B)> Dimensioni (A), forse esponendo i dati indesiderati. In ogni caso, controllare sempre i confini della struttura quando si spostano i dati - alcune aziende operazioni vietate in questo modo (cioè memcpy ()) dal loro codice
.