![]() |
Error: Inkompatible Typen Reguläre Prozedur u Methodenzeiger
Ich habe mir eine eigene Klasse von TList abgeleitet. Dieser möchte ich eine Sortierfunktion hinzufügen. Dazu muss man der vorhandenen TList-Funktion Sort etwas vom Typ TListSortCompare übergeben. Ich bekomme es nicht hin. An der markierten Stelle kommt die Fehlermeldung "Inkompatible Typen: Reguläre Prozedur und Methodenzeiger"
Delphi-Quellcode:
TMyList = class(TList)
private SortedColumn: Integer; function MyListSortCompare(Item1, Item2: Pointer): Integer; public procedure SortByColumn(Column: Integer); end; procedure TMyList.SortByColumn(Column: Integer); begin SortedColumn := Column; Sort(MyListSortCompare); //<-- FEHLER: Inkompatible Typen: Reguläre Prozedur und Methodenzeiger end; function TMyList.MyListSortCompare(Item1, Item2: Pointer): Integer; begin result := MachWas(Item1, Item2, SortedColumn); end; |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
self.Sort()
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Zitat:
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
MyListSortCompare muss eine einfache Funktion sein, keine Methode. Deklariere sie also nicht in der Klasse und lasse das TMyList bei der Definition weg.
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Zitat:
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Was sind denn deine Listenelemente?
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Zitat:
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
![]() |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Hi Apollonius,
Assembler kann ich leider gar nicht. Ich wäre Dir also sehr dankbar, wenn Du (oder andere) es mal probieren würden. |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Es dürfte reichen deiner Methode ein stdcall anzuhängen.
Delphi-Quellcode:
TMyList = class(TList)
private SortedColumn: Integer; function MyListSortCompare(Item1, Item2: Pointer): Integer; stdcall; public procedure SortByColumn(Column: Integer); end; procedure TMyList.SortByColumn(Column: Integer); var MyListComparef:function(Item1,Item2:Pointer):integer; begin SortedColumn := Column; MyListcomparef:=MakeProcInstance(MyListcompare); Sort(MyListSortComparef); //<-- FEHLER: Inkompatible Typen: Reguläre Prozedur und Methodenzeiger FreeProcinstance(MyListcompareF); end; function TMyList.MyListSortCompare(Item1, Item2: Pointer): Integer; begin result := MachWas(Item1, Item2, SortedColumn); end; |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Das klappt so leider auch nicht. Es kommt ein neuer Fehler:
Delphi-Quellcode:
TMyList = class(TList)
private SortedColumn: Integer; function MyListSortCompare(Item1, Item2: Pointer): Integer; stdcall; public procedure SortByColumn(Column: Integer); end; procedure TMyList.SortByColumn(Column: Integer); var MyListComparef:function(Item1,Item2:Pointer):integer; begin SortedColumn := Column; MyListcomparef:=MakeProcInstance(MyListSortCompare); //<-- Fehler: Nicht genügend wirkliche Parameter Sort(MyListSortCompare); FreeProcinstance(MyListcompareF); end; function TMyList.MyListSortCompare(Item1, Item2: Pointer): Integer; begin result := MachWas(Item1, Item2, SortedColumn); end; |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Delphi-Quellcode:
TMyList = class(TList)
protected SortedColumn: Integer; public procedure SortByColumn(Column: Integer); end; implementation var _sortlist: TMyList; // globale hilfsvariable // "normale" Funktion function MyListSortCompare(Item1, Item2: Pointer): Integer; begin result := MachWas(Item1, Item2, _sortlist.SortedColumn); end; procedure TMyList.SortByColumn(Column: Integer); begin SortedColumn := Column; _sortlist := self; Sort(MyListSortCompare); end; |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
... Oder einfach ein QuickSort selber implementieren...
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
:gruebel: Das muss auch einfach ohne ASM gehen
Delphi-Quellcode:
Wie weist man nur m eine Methode zu? :gruebel:
procedure TMyList.SortByColumn(Column: Integer);
var MyListComparef:function(Item1,Item2:Pointer):integer; m:Tmethod; begin SortedColumn := Column; asm //m.code:=@MyListCompare (ging leider nur so) push edi mov edi, offset MyListCompare mov m.code,edi pop edi end; m.Data:=self; MyListcomparef:=MakeProcInstance(m); //<-- Fehler: Nicht genügend wirkliche Parameter Sort(MyListSortCompare); FreeProcinstance(MyListcompareF); end; |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Zitat:
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Zitat:
Delphi-Quellcode:
Und zum Code "der Schweizer" muss ich sagen: Viel glück unter Systemen mit aktivierter Data Execution Prevention (DEP).
m.Code := @TMyList.MyListCompare;
Delphi-Quellcode:
type
TSortCompareMethod = function(Item1, Item2: Pointer): Integer of object; procedure MQuickSort(SortList: PPointerList; L, R: Integer; SCompare: TSortCompareMethod); var I, J: Integer; P, T: Pointer; begin repeat I := L; J := R; P := SortList^[(L + R) shr 1]; repeat while SCompare(SortList^[I], P) < 0 do Inc(I); while SCompare(SortList^[J], P) > 0 do Dec(J); if I <= J then begin if I <> J then // kleine zusätzliche Optimierung begin T := SortList^[I]; SortList^[I] := SortList^[J]; SortList^[J] := T; end; Inc(I); Dec(J); end; until I > J; if L < J then MQuickSort(SortList, L, J, SCompare); L := I; until I >= R; end; procedure TMyList.Sort(Compare: TListSortCompareMethod); begin if (FList <> nil) and (Count > 0) then MQuickSort(FList, 0, Count - 1, Compare); end; |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Zitat:
Ich habe heute auch einen schweren Tag hintermir. Zitat:
![]() Edit: Ich sollte besser ins Bett |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Fertig.
Delphi-Quellcode:
Ihr Assemblerkundigen da draußen, nehmt es mal kritisch unter die Lupe.
function MakeListSortMethodProc(Method:TListSortMethod): TListSortCompare;
begin Pointer(result):=VirtualAlloc(0, $0F, MEM_COMMIT, PAGE_EXECUTE_READWRITE); asm //mov ecx, edx mov [eax], $D189 //mov edx, eax mov [eax+$02], $C289 //mov eax, Method.Data mov [eax+$04], $B8 mov ecx, [ebp+$0C] mov [eax+$05], ecx //push Method.Code mov [eax+$09], $68 mov ecx, [ebp+$08] mov [eax+$0A], ecx //ret mov [eax+$0E], $C3 end; end; procedure FreeListSortProc(Proc: TListSortCompare); begin VirtualFree(Pointer(@Proc), 0, MEM_RELEASE); end; [Edit] Zusätzlich zu Sirius' Korrektur nocheinmal 6 Bytes Assemblercode gespart. [/edit] |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Zitat:
Also, vorausgesetzt, dein Kommentar passt zu den Opcodes, denn fehlt ein "$C3"=return am Ende. |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Tja, sowas kommt davon, sich selbst zu hetzen :( Ist korrigiert.
[edit] Nachtrag zum Thema hetzen: Buchstabendreher kommen auch daher.[/edit] |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Habe mir Diese Thema nun schon 9 mal durchgelsesen.. und steige da einfahc nicht hinter.. währe nett wenn es jemand noch mal füür dumme erklären würde....
An sich habe ich das selbe Problem.... allergings habe ich keinen plan wie die eizelneen sachen aber definiert werden müssen. also ich möchte auch erreichen das die sortierfunktion in einer klasse ist, damit ich davon mehrere instanzen erzeugen kann... bekomme ich diese fehlermeldung:
Delphi-Quellcode:
der Quelltext sieht folgenermaßenn aus:
[DCC Fehler] ExtGrid.pas(253): E2009 Inkompatible Typen: 'Reguläre Prozedur und Methodenzeiger'
Delphi-Quellcode:
Type TExtStrGrid=Class
SortCol:integer; SortDir:integer; PicUp:TImage; PicDown:TImage; LastDummy:boolean; SRow:integer; mausdown:boolean; Function CompareStringGridRows(item1,item2: Pointer):integer; Procedure DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure SortGrid(thegrid: TStringGrid; const col: integer); Constructor Create; destructor Destroy; end; implementation .. .. .. Function TExtStrGrid.CompareStringGridRows(item1,item2: Pointer):integer; var c1,c2: ^char; n1,n2: integer; begin c1 :=@TStrings(item1).Strings[sortcol][1]; c2 :=@TStrings(item2).Strings[sortcol][1]; while (c1^ <>#0) and (c2^ <>#0) do begin if ((c1^ in ['0'..'9']) and (c2^ in ['0'..'9'])) then begin n1 :=0; n2 :=0; while (c1^ in ['0'..'9']) do begin .. .. .. procedure TextStrGrid.SortGrid(thegrid: TStringGrid; const col: integer); var rows: TList; id,i,j: integer; tmp: TStrings; tmp_row:string; begin try rows :=TList.Create; rows.Capacity :=thegrid.RowCount-thegrid.fixedrows; for i:=theGrid.fixedrows to thegrid.RowCount -1 do begin tmp :=TStringList.Create; for j:=0 to thegrid.ColCount-1 do tmp.AddObject(thegrid.cells[j,i],thegrid.Objects[j,i]); thegrid.Rows[i].Clear; rows.Add(tmp); end; rows.Sort(CompareStringGridRows); // Hier die Fehlermeldung.. for i:=thegrid.fixedrows to thegrid.RowCount -1 do begin |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Delphi-Quellcode:
So ist das eine Methode von TExtStrGrid.
Function TExtStrGrid.CompareStringGridRows(item1,item2: Pointer):integer;
Delphi-Quellcode:
Und so ist das eine Funktion. Nun klarer?
Function CompareStringGridRows(item1,item2: Pointer):integer; stdcall;
|
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Zitat:
Hilft mir nicht wirklick weiter... wenn ich nur den Stdall hinter Setzte bekomme ich die Fehlermeldung:
Delphi-Quellcode:
Ich werde aus den Ganzen kram nicht schlau...
[DCC Fehler] ExtGrid.pas(253): E2009 Inkompatible Typen: 'Unterschiede in der Aufrufkonvention'
Wie binde ich den Assembler Code richitg ein ? ... Im Moment komme ich mir richtig doof vor ..... |
Re: Error: Inkompatible Typen Reguläre Prozedur u Methodenze
Delphi-Quellcode:
Versuch es mal so.
Type TExtStrGrid=Class
SortCol:integer; SortDir:integer; PicUp:TImage; PicDown:TImage; LastDummy:boolean; SRow:integer; mausdown:boolean; // Function CompareStringGridRows(item1,item2: Pointer):integer; Procedure DrawCell(Sender: TObject; ACol, ARow: Integer; Rect: TRect; State: TGridDrawState); procedure MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure SortGrid(thegrid: TStringGrid; const col: integer); Constructor Create; destructor Destroy; end; implementation .. .. .. Function {TExtStrGrid.}CompareStringGridRows(item1,item2: Pointer):integer; var c1,c2: ^char; n1,n2: integer; begin c1 :=@TStrings(item1).Strings[sortcol][1]; c2 :=@TStrings(item2).Strings[sortcol][1]; while (c1^ <>#0) and (c2^ <>#0) do begin if ((c1^ in ['0'..'9']) and (c2^ in ['0'..'9'])) then begin n1 :=0; n2 :=0; while (c1^ in ['0'..'9']) do begin .. .. .. procedure TextStrGrid.SortGrid(thegrid: TStringGrid; const col: integer); var rows: TList; id,i,j: integer; tmp: TStrings; tmp_row:string; begin try rows :=TList.Create; rows.Capacity :=thegrid.RowCount-thegrid.fixedrows; for i:=theGrid.fixedrows to thegrid.RowCount -1 do begin tmp :=TStringList.Create; for j:=0 to thegrid.ColCount-1 do tmp.AddObject(thegrid.cells[j,i],thegrid.Objects[j,i]); thegrid.Rows[i].Clear; rows.Add(tmp); end; rows.Sort(@CompareStringGridRows); // Hier die Fehlermeldung.. for i:=thegrid.fixedrows to thegrid.RowCount -1 do begin |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz