Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi E2010 Inkompatible Typen: 'Integer' und 'Pointer' (https://www.delphipraxis.net/118487-e2010-inkompatible-typen-integer-und-pointer.html)

bl3nder 8. Aug 2008 15:12


E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Hallo,


Ich versuch mich grade an einem Model View Controller. Hierzu habe ich unter anderem 2 Units die mit einander kommunizieren.

Model.pas
Model_Database.pas


Model_Database.pas sieht vereinfacht so aus:


Delphi-Quellcode:
unit Model_Database;

interface

uses
  ZConnection,ZDataset,DBgrids, ZAbstractRODataset,
  ZAbstractDataset,ZSysUtils,ZPlainMySqlDriver,DB,Classes;

type

  TDatabase = class(TObject)
  private
    SQLQuery: TZQuery;
    DataSource: TDataSource;
    SQLConnection: TZConnection;
  public
    constructor Create();
    function DBSearch: TList; virtual; abstract;
    //...
  end;





  TWorkStationSearch = class(TDatabase)
  private
  public
    function DBSearch: TList; override;
  end;




implementation

uses Model;


//...


function TWorkstationSearch.DBSearch: TList; override;
var List: TList;
begin
  SQLQuery.SQL.Text := 'SELECT * FROM Workstations';
  SQLQuery.Open;

  while not SQLQuery.EOF do
    List.Add(SQLQuery.FieldByName('WorkstationID'));

  Result := List;
end;



end.


Model.pas sieht verkürtzt so aus

Delphi-Quellcode:

unit Model;

interface

uses
  ZConnection,ZDataset,DBgrids, ZAbstractRODataset,
  ZAbstractDataset,ZSysUtils,ZPlainMySqlDriver,DB,Contnrs,Classes,SysUtils,
  Model_Database;

type
 

  TMain = class(TObject)
  private
  public

    function DBSearch(): TObjectList; Virtual; Abstract;
    //...
  end;


//...


  TWorkstation = class(TMain)
  private
    ID: Integer;
    Username: String;
    Room: String;
    FormerUserName: String;
    Documentation: String;

  public
    constructor Create(DatabaseID: Integer);
    destructor Destroy();


    function GetUsername: String;
   
    //...

  end;




  TWorkstationSearch = class(TMain)
  private
  public
    function DBSearch(): TObjectList; Override;
  end;




implementation

constructor TWorkstation.Create(DatabaseID: Integer);
begin
  ID := DatabaseID;
  Username := 'testname'+IntToStr(DatabaseID);
  Room := '123';
  FormerUsername := 'alt';
  Documentation := 'nc';
end;




function TWorkstation.GetUsername;
begin
  Result := Username;
end;



function TWorkstationSearch.DBSearch;
var WsSearch: Model_Database.TWorkstationSearch;
var Workstation: TWorkstation;
var List: TList;
var WsList: TObjectList;
var I: Integer;
begin
  I := 0;
  List := WsSearch.DBSearch();
  while (I<List.Count) do
  begin
    Workstation.Create(List[I]); // <------------------ FEHLERZEILE
    WsList.Add(Workstation);
    Workstation.Destroy;
    Inc(I);
  end;

  Result := WsList;
end;



end.


Beim Kompilieren von Model.pas sagt er mir dann den folgenden Fehler:

Zitat:

[Pascal Fehler] Model.pas(279): E2010 Inkompatible Typen: 'Integer' und 'Pointer'


Wieso ist die Liste nicht eine Liste von Integern ? So habe ich es doch in obigen Funktion deklariert. Oder etwa nicht ?

DeddyH 8. Aug 2008 15:16

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Mal abgesehen davon, dass ich eine Liste nicht als Funktionsrückgabewert definieren würde: TList ist eine Liste von Pointern. Das sind zwar intern 32-Bit-Integer, trotzdem musst Du casten.
Delphi-Quellcode:
List.Add(Pointer(SQLQuery.FieldByName('WorkstationID')));
P.S.: Wo ist eigentlich das TList.Create? Hab ich das übersehen?

Apollonius 8. Aug 2008 15:16

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Erstmal: Ein var reicht.
TList ist eine Liste von Pointern. Wenn du eine Integer-Liste willst, musst du casten.

Objekte werden mit Instanz := TKlasse.Create erzeugt, nicht mit Instanz.Create.
Auch Listen sind Objekte, die du erzeugen musst.

Außerdem darfst du das Objekt nicht gleich wieder freigeben.

SirThornberry 8. Aug 2008 15:19

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Delphi-Quellcode:
constructor TWorkstation.Create(DatabaseID: Integer);
da steht eindeutig integer und du übergibst eben einen Pointer. Von daher verstehe ich nicht was an der Fehlermeldung seltsam sein soll.

DeddyH 8. Aug 2008 15:19

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Zitat:

Zitat von DeddyH
TList ist eine Liste von Pointern.

Zitat:

Zitat von Apollonius
TList ist eine Liste von Pointern.

:lol:

Apollonius 8. Aug 2008 15:22

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Das habe ich getippt, bevor der rote Kasten kam. :P

DeddyH 8. Aug 2008 15:29

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
[OT] Ich finde es nur witzig, dass der Wortlaut haargenau übereinstimmt :zwinker: [/OT]

Medium 8. Aug 2008 15:36

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Sogar die Uhrzeit. Das ist ein Omen! Evtl... :gruebel:

DeddyH 8. Aug 2008 15:41

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
:shock: Die letzte Person, bei der mir das häufiger passiert ist, habe ich geheiratet. :-D

bl3nder 12. Aug 2008 09:31

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Hallo,

Danke fuer die Antworten,

Ich habe nun auch die Liste und die Instanzen durch
Delphi-Quellcode:
List := TList.Create;
und
Delphi-Quellcode:
Workstation := TWorkstation.Create(List[I]);
erstellt.

Dennoch ändert das nichts am Problem. Dass ich die Instanz wieder freigebe liegt daran, dass in jeder Schleife eine neue Instanz angelegt werden soll, sodass in der Liste nicht öfter das gleiche Objekt zu finden ist. Vielleicht habe ich da aber auch ein Vorstellungsproblem. Soweit ist noch Workstation.Destroy mit eingebaut...

Delphi-Quellcode:
function TWorkstationSearch.DBSearch;
var
WsSearch: Model_Database.TWorkstationSearch;
Workstation: TWorkstation;
List: TList;
WsList: TObjectList;
I: Integer;
begin
  I := 0;
  List := TList.Create;
  List := WsSearch.DBSearch();
  while (I<List.Count) do
  begin
    Workstation := TWorkstation.Create(List[I]);
    WsList.Add(Workstation);
    Workstation.Destroy;
    Inc(I);
  end;

  Result := WsList;
end;

Nun weiß ich nicht genau, wie ich diese Liste von Pointern casten kann, sodass in der Liste nur die Datenbank IDs stehen.
Würde mir jemand auf die Sprünge helfen ?

Danke
Mfg

Die Muhkuh 12. Aug 2008 10:07

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Hi,

da der Code gekürzt ist, weiß ich nicht, ob Du zu viel gekürzt hast oder ob es einfach fehlt.

Delphi-Quellcode:
while not SQLQuery.EOF do
    List.Add(SQLQuery.FieldByName('WorkstationID'));
Fehlt hier nicht noch ein SQLQuery.Next?

bl3nder 12. Aug 2008 10:11

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Danke das hat unter anderem auch noch gefehlt :roll:


Die DBSearch funktion sieht mittlerweile so aus


Delphi-Quellcode:
function TWorkstationSearch.DBSearch;
var
WsSearch: Model_Database.TWorkstationSearch;
Workstation: TWorkstation;
List: TList;
WsList: TObjectList;
I: Integer;
begin
  I := 0;
  List := TList.Create;
  List := WsSearch.DBSearch();
  while (I<List.Count) do
  begin
    Workstation := TWorkstation.Create(Integer(List[I]));
    WsList.Add(Workstation);
    Workstation.Destroy;
    Inc(I);
  end;

  Result := WsList;
end;
Nun bringt er mir diesen Fehler
Zitat:

[Pascal Fehler] ViewController.pas(40): E2010 Inkompatible Typen: 'TWorkstation' und 'TObject'
Mir ist der Fehler schon bewusst, ich weiß allerdings nicht wie ich das jetzt löse. Ich kann ja nicht eine WsList: TWorkstationList anlegen...

DeddyH 12. Aug 2008 10:22

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
*Uhh*, Listen als Funktionsrückgabewert, Funktionen ganz ohne Rückgabewert, fehlendes Instanziieren von Listen... ich steig da nicht mehr richtig durch.

p80286 12. Aug 2008 10:48

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Hallo zusammen,
Zitat:

begin
Workstation := TWorkstation.Create(Integer(List[I]));
WsList.Add(Workstation);
Workstation.Destroy;
Inc(I);
end;
wenn ich das richtig verstehe wird da eine "Workstation" erstellt, in eine Liste gepackt, und danach gelöscht.
D.h die Einträge der Liste zeigen irgendwo in die Botanik, oder hab ich da irgendetwas falsch verstanden?

Und ansonsten geht es doch um eine Liste von "Workstation-ID"s, da damit nicht gerechnet werden muß/darf, würde ich die als Strings in eine TStringlist packen und gut ist. Doppelte Einträge kann man prima durch sortieren und vergleichen finden, oder im Vorfeld bei der Abfrage durch
Delphi-Quellcode:
Select distinct * from..
oder
Select distinct WorkstationID from..
.

edit:
Die restlichen Informationen (Username,Room etc.) erst abholen wenn ich weiß was ich brauche, das verringert den Traffic doch ganz schön


Gruß
K-H

bl3nder 12. Aug 2008 10:49

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Ok ich gebe zu es ist ziemlich unübersichtlich geworden, nochmal zur Erklärung:

In meiner Datenbank hab ich eine Tabelle "Workstation". Diese hat neben einer ID auch Username etc.

In meinem Model_Database.pas habe ich nun die SQL Abfrage in einer Funktion die so aussieht:

Delphi-Quellcode:
// Wird in Model.TWorkstationSearch.DBSearch aufgerufen
function TWorkstationSearch.DBSearch;
var List: TList;
begin
  List := TList.Create;
  SQLQuery.SQL.Text := 'SELECT * FROM Workstation';
  SQLQuery.Open;

  while not SQLQuery.EOF do
  begin
    List.Add(SQLQuery.FieldByName('WorkstationID'));
    SQLQuery.Next;
  end;
  Result := List;
end;
Die Funktion soll eine Liste mit den IDs der gefundenen Datensätze zurückliefern (Integer)



Nun benutzt eine Funktion in Model.pas die obige Funktion (Beide Funktionen besitzen leider den gleichen Namen)

Delphi-Quellcode:
function TWorkstationSearch.DBSearch;
var
WsSearch: Model_Database.TWorkstationSearch;
MyWorkstation: TWorkstation;
List: TList;
WsList: TObjectList;
I: Integer;
begin
  I := 0;
  List := TList.Create;
  List := WsSearch.DBSearch(); // Ruft Model_Database.TWorkstationSearch.DBSearch auf
                               // Die Liste sollte nun mit den Datenbank IDs befüllt sein

  while (I<List.Count) do
  begin
    MyWorkstation := TWorkstation.Create(Integer(List[I])); // Ruft den constructor auf
    WsList.Add(MyWorkstation); // <--- Hier wird einer TObjectList ein TWorkstation Objekt übergeben, ka ob das so geht...
    Inc(I);
  end;

  Result := WsList;
end;



// wird in Model.TWorkstationSearch.DBSearch aufgerufen
constructor TWorkstation.Create(DatabaseID: Integer);
begin
  ID := DatabaseID;
  Username := 'testname'+IntToStr(DatabaseID);
  Room := '123';
  FormerUsername := 'alt';
  Documentation := 'nc';
end;








In meiner ViewController.pas möchte ich nun einen Testlauf durchführen:


Delphi-Quellcode:
procedure TMainForm.JvTransparentButton1Click(Sender: TObject);
var
MyWorkstation: Model.TWorkstation;
WsSearch: Model.TWorkstationSearch;
WsList: TObjectList; // <-- Hier will ich alle Workstations in eine Liste packen
I: Integer;
begin
  I := 0;
  WsList := WsSearch.DBSearch();
  while (I<WsList.Count) do
  begin
    MyWorkstation := WsList[I]; // <--- [Pascal Fehler] ViewController.pas(40): E2010 Inkompatible Typen: 'TWorkstation' und 'TObject'
    Showmessage(MyWorkstation.GetUsername);
    Inc(I);
  end;
end;

DeddyH 12. Aug 2008 11:03

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Nochmal:
Zitat:

Delphi-Quellcode:
function TWorkstationSearch.DBSearch;

Die Funktion hat keinen Rückgabewert.
Zitat:

Delphi-Quellcode:
WsList.Add(MyWorkstation); // <--- Hier wird einer TObjectList ein TWorkstation Objekt übergeben, ka ob das so geht...

Ohne ein WsList := TObjectList.Create davor wohl eher nicht :stupid:
Zitat:

Delphi-Quellcode:
MyWorkstation := WsList[I]; // <--- [Pascal Fehler] ViewController.pas(40): E2010 Inkompatible Typen: 'TWorkstation' und 'TObject'

Delphi-Quellcode:
MyWorkstation := WsList[I] as Model.TWorkstation; // der Fehler sollte nun weg sein
Aber ich würde die Listen als Parameter übergeben, das mindert die Gefahr von Speicherlecks.

jottkaerr 12. Aug 2008 12:53

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Zitat:

Zitat von DeddyH
Nochmal:
Zitat:

Delphi-Quellcode:
function TWorkstationSearch.DBSearch;

Die Funktion hat keinen Rückgabewert.

Das ist nicht ganz richtig. Nach einer Vorwärts-Deklaration -- und nicht nur eine forward-Deklaration, sondern auch die Nennung einer Methode innerhalb einer Klassendeklaration und jede Deklaration im interface-Teil stellen eine solche dar -- kann die Angabe der Parameter und Rückgabewerte bei der Implementierung entfallen. Ausnahmen sind allerdings überladene Prozeduren, Funktionen und Methoden; hier sind die Parameter und Rückgabewerte notwendig, damit der Compiler sie auseinander halten kann. Beispiel:

Delphi-Quellcode:
unit Test;

interface

type
  TMyClass = class(TObject)
    function FuncOne(a: Integer): Integer;
    procedure ProcOne(const s: string);
  end;

function FuncTwo(const x, y: Double): Double;

implementation

uses
  Dialogs, SysUtils;

function FuncThree(const s: string): string; forward;

function TMyClass.FuncOne;
begin
  Result := 2 * a;
end;

procedure TMyClass.ProcOne;
begin
  ShowMessage(s);
end;

function FuncTwo;
begin
  Result := x + y;
end;

function FuncThree;
begin
  Result := UpperCase(s);
end;

end.

DeddyH 12. Aug 2008 13:01

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Schau an, das war mir neu. Danke für die Erläuterung :thumb:

bl3nder 12. Aug 2008 13:13

Re: E2010 Inkompatible Typen: 'Integer' und 'Pointer'
 
Danke für eure Hilfe !
Zumindest mit einer Stringlist hat es jetzt funktioniert. Nun habe ich noch Probleme mit der Zeos Komponente, dazu werde ich einen anderen Thread erstellen (hoffentlich ist das ok..)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:47 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz