![]() |
Pointer - ein schwarzes Tuch
Hallo DP,
ich möchte mich in die API-Programmierung einarbeiten, hatte nur bisher noch keine sinnvolle Idee, was ich als "Übungsaufaufgabe" probieren könnte. Nun habe ich aber ein Thema: RAPI (Remote-API) Dafür habe ich mir eine RAPI.pas von Pegasus Remote API besorgt. Jetzt wollte ich die function CeFindAllDatabases rufen, die erwartet aber als vierten Parameter einen "Berg" von Pointern. Mit Pointern habe ich schon immer Probleme. Irgendwie ist mir die ganze Sache zu hoch. Ich hab mir schon eine ganze Reihe vom Pointer-Tuts durchgelesen - aktuell habe ich wieder das Tut von Manuel Pöter vor mir - ich kapiere es einfach nicht. Die Beispiele die dort aufgeführt werden, sind alle nach zu vollziehen - mehr oder weniger - aber an der praktischen Umsetzung hapert's bei mir. Deshalb hab ich in den letzten Jahren, in alle Sprachen mit denen ich zu tun hatte, einen großen Bogen um Pointer gemacht. Ich wills aber verstehen, denn schließlich soll das Arbeiten mit Pointer relativ einfach sein, wenn man's erst mal kapiert hat. Mein Problem deklariert sich so:
Delphi-Quellcode:
Der Aufruf von CeFindAllDatabases funktioniert. Also scheinen ja Datenbank vorhanden zu sein, aber wie komme ich z.B. an den Namen (CeDBaseInfo.szDbaseName) rann ?
[...]
TCeDBaseInfo = record dwFlags:DWORD; szDbaseName:array [0..CeDB_MAXDBASENAMELEN-1] of WCHAR ; dwDbaseType:DWORD; wNumRecords:WORD; wNumSortOrder:WORD; dwSize:DWORD; ftLastModified:TFileTime; rgSortSpecs:array [0..CeDB_MAXSORTORDER-1] of TSortOrderSpec; end; TCeDB_File_Data = record OidDb:CeOID ; DbInfo:TCeDBaseInfo ; end; PCeDB_File_Data=^TCeDB_File_Data; TCeDB_File_Data_Array = array [0..MaxInt div sizeof(TCeDB_File_Data)-1] of TCeDB_File_Data; PCeDB_File_Data_Array = ^TCeDB_File_Data_Array; [...] function CeFindAllDatabases(dwDbaseType:DWORD; wFlags:WORD; var cFindData:DWORD; var ppFindData:PCeDB_File_Data_Array):BOOL ; Könnt ihr mir Zeigen wie ich das bewerkstelligen muß. 1000 Dank schon mal im Voraus. gmc [edit=SirThornberry]Titel korrigiert - Mfg, SirThornberry[/edit] |
Re: Pionter - ein schwarzes Tuch
Du bist jetzt eigentlich schon lange genug dabei, dass du wissen müsstest, dass man für seinen Beitrag einen aussagekräftigen Titel wählen sollte. :roll:
|
Re: Pionter - ein schwarzes Tuch
Das finde ich Schade, dass du meinst, mein Hilferuf bedürfe einen noch genaueren Titel.
Ich habe den Post ins Board API-Programmierung geschrieben. Der Titel "Pointer" besagt, es hier um Pointer geht wird. Vielleicht kennst du die Redewendung "Ein schwarzes Tuch" nicht, welche eigentlich besagt "Depp, der nix kapiert". Ich denke damit habe ich mein Problem grob rum rissen. Ich hätte nur gern gezeigt, an einem konkreten Beispiel, wie man mit Pointer arbeitet, denn alle Tuts die ich lesen habe, helfen mir nicht weiter. Wahrscheinlich bin ich zu blöd dafür. :stupid: Das es in meinem Post um RAPI, speziell CeFindAllDatabases, geht, ist eigentlich nur zweitrangig. Wäre aber schön genau diese Problem erklärt zu bekommen. Vor diesem Hintergrund habe ich den Titel so gewählt. Ich glaube mir hilft kein weiteres Tut weiter, noch ein Link aufs mdsn. Davon hab ich genug. Nur eine Erklärung im Umgang mit Pointern, speziell an diesem Beispiel, wäre hilfreich. Okay, da du ein Moderator über dieses Board bist, möchte ich dich bitten, meinem Thema einen angemessenen Titel zu geben, denn mir fällt i.M. keiner ein. :wink: Danke. |
Re: Pionter - ein schwarzes Tuch
Und wie wäre es mit: "Verständsnisproblem bezüglich Pointern"?
|
Re: Pionter - ein schwarzes Tuch
Du musst es dereferenzieren
Ein ganz simples Pointer HowTo
Delphi-Quellcode:
Ich garantiere keine 100% Korrektheit :)
{
Grundlegende Sachen zu Pointern: o Pointer belegen immer 4 Bytes o Pointer beinhalten die Adresse zur "hingepointetten"(hingezeigten) Variable und natürlich die eigene Adresse (sowie alle anderen Typen) o Es gibt 2 verschiedene Pointertypen: a) typisierte Pointer (bsp "PInteger") // so nenne ich sie mal .. da gibts sicher andere Begriffe dafür - ist mir aber jetzt wurscht b) untypisierte Pointer ("Pointer") o a Pointer können direkt dereferenziert werden wohingegen o b Pointer gecastet werden müssen } // -- A.) var X: Integer; P: PInteger; // Pointer auf einen Integer ! ... // Adressen sind zum Demonstrationszweck frei gewählt ! X := 12345; // Adresse von X - $00ABCDEF; Wert von X = 12345 P := @X; // Adresse von P - $00FEEFEE; Wert von P = $00ABCDEF // jetzt zeigt unser Pointer P auf X // wenn wir nun die Werte verändern wollen "dereferenzieren" wir es wie folgt P^ := 54321; // Adresse von P - $00FEDCAB; Wert von P = $00ABCDEF // der Wert & die Adresse haben sich nicht geändert // da wir sie aber dereferenziert haben, haben wir somit auf X zugegriffen: // X hat jetzt den Wert 54321! // -- B.) var PInt: Pointer; ... PInt := @X; Integer( PInt^ ) := 113245; |
Re: Pointer - ein schwarzes Tuch
Hallo mr_emre_d,
ich hab's überflogen und dem ist eigentlich nichts hizuzufügen, bis auf... (der Hinweis auf bigendian ist nicht so offensichtlich) Wenn ich mich richtig an API-Aufrufe erinnere, dann sind dort die "Pointer" das, was in Delphi/Pascal die var -Übergaben sind. Wenn also etwa folgendes verlangt wird:
Delphi-Quellcode:
dann solte das in Pascal/Delpi so gelöst werden:
API_funktion(pbytearr):bool
Delphi-Quellcode:
oder
var
mybytearr : array[0..255] of byte; if API_Funktion(@mybytearray) then ...
Delphi-Quellcode:
da gibt's bestimmt Empfehlungen wie's am Besten ist, aber die hab ich gerade nicht zur Hand.
type
tmybytearray = array [0..255] of byte; var mybytearray : tmybytearray; pmybytearray : ^tmybytearray; ... pmybytearray:=@mybytearray; if API_Funktion(pmybytearray) then ... Vielleicht ist in diesem Zusammenhang "Adresse" eine bessere Übersetzung als "Zeiger". (Fehlinterpretatinen meinerseits bitte ich zu berichtigen) Gruß K-H |
Re: Pointer - ein schwarzes Tuch
Der vierte Parameter in der Funktion enthält die Daten.
In deinem konkreten Fall:
Delphi-Quellcode:
var
ppFindData: PCeDB_File_Data_Array i: Integer; begin // ... New (ppFindData); try if CeFindAllDatabases(.., .., ..., ppFindData) then begin // ... i := 0; while TRUE do begin ShowMessage (ppFindData^[i].DbInfo.szDbaseName); inc (i); // Abbruchbedingung is mir grad unklar end; end; finally Dispose (ppFindData); end; // ... end; |
Re: Pointer - ein schwarzes Tuch
Zitat:
Delphi-Quellcode:
buf = PChar --> Pointer zu (m ersten) Char (acter eines Strings, das Null-Terminiert ist)
GetWindowText( hWnd, Buf );
dh. man könnte sich ein Buffer wie folgt definieren:
Delphi-Quellcode:
welches 256 Zeichen beinhalten kann und somit ->Buf entspricht !
buf: Array[Byte] of Char;
EDIT: Bei der Übergabe eines Parameters an eine (API) Funktion kommt es darauf an, was verlangt wird: Wenn ein Pointer verlangt wird, heißt es in meisten Fällen, dass der Wert verändert werden können muss! Deshalb könnte man auch vars übergeben, da sie (ne wage Behauptung - da Halbwissen -->) intern als Pointer verwertet werden !
Delphi-Quellcode:
Bei a wird nur der Inhalt von "Input" kopiert und übergeben!
a. procedure ChangeInput(Input: Integer);
b. procedure ChangeInput(var Input: Integer); b. procedure ChangeInput(Input: PInteger); Bei beiden bs wird die Referenz übergeben - man kann den Wert verändern ! Ist jetzt ziemlich weit hergeholt aber sollte halt das ganze ein bisschen veranschaulichen Natürlich garantiere ich wieder nicht auf 100% Richtigkeit meiner Angaben - da sie auf Erfahrung beruhen :D MfG |
Re: Pointer - ein schwarzes Tuch
Erst mal Danke Leute, für die Hilfe.
Das was ihr geschrieben habt ist im groß und ganzen auch das, was ich aus den Tuts entnehemn konnte. Was Pointer sind und wie sie funktionieren ist mir durchaus klar. Natürlich habe ich das Beispiel von nuclearping probiert, aber ich bekomme ein EOutOfMemory - Zu wenig Arbeitsspeicher auf der Zeile
Delphi-Quellcode:
"Ach, die Fehlermeldungen kennst! Gut!" dachte ich mir.
New (ppFindData);
ppFindData weiß ja noch nicht, wohin er zeigen soll, damit das New weiß wieviel speicher es reservieren muß. Also
Delphi-Quellcode:
Nun stürzt das Programm bereits beim Aufruf der procedure LeseDB mit EStackOverflow ab.
procedure TFrom1.LeseDB();
var FindData : TCeDB_File_Data_Array; ppFindData: PCeDB_File_Data_Array; // ... ppFindData := @FindData; New (ppFindData); Okay. Völlig Falsch. :oops: Könnte wohl daran liegen, dass jetzt das New Speicher reservieren soll, der bereits reserviert ist. Oder? :gruebel: Das muß ja in die Hose gehen. Letzten Endes müsste New eigentlich wissen, wie viel Speicher reserviert werden muß, da PCeDB_File_Data_Array bzw. ppFindData ein typisierter Pointer ist. Richtig ? :gruebel: Aber eigentlich sollte das ganze doch auch ohne New funktionen, denn mit
Delphi-Quellcode:
habe ich doch meinen Zeiger auf das FindData : TCeDB_File_Data_Array ??
ppFindData := @FindData;
Knallt aber ebenfalls mit EStackOverflow. Jetzt bin ich der gleichen Stelle, an der ich heute Mittag schon war. :cry: Und nu? Die Hilfe zu New sagt: Zitat:
Delphi-Quellcode:
EOutOfMemory - Zu wenig Arbeitsspeicher
GetMem (ppData,SizeOf (TCeDB_File_Data_Array));
Bin ich echt zu blöd dafür? :duck: |
Re: Pointer - ein schwarzes Tuch
Achtung - das ist nicht nur ein Pointer auf ne Variable sondern auf ein Array.
bsp:
Delphi-Quellcode:
anderes, ähnliches bsp:
type
PByteArr = ^TByteArr; TByteArr = Array of Byte; var X: PByteArr; begin New( X ); SetLength( X^, 10 ); X^[0] := $FF; Dispose( X ); ...
Delphi-Quellcode:
Edit: Hab gerade deinen Code ausprobiert und ja bei mir haut er auch "Zu wenig Arbeitsspeicher" raus ... ist iwie klar denn du hast ein Array, welches
type
PByteArr = ^TByteArr; TByteArr = Array[0..0] of Byte; var X: PByteArr; Test: Array[0..10] of Byte; i: Integer; begin Randomize; for i := 0 to High(Test) do Test[i] := Random(10); X := @Test; ShowMessage( inttostr(x^[0]) ); ( $7FFFFFFF div sizeof(TCeDB_File_Data)-1 ) * SizeOf( TCeDB_File_Data ) --> also $7FFFFFFF=2147483647 Bytes (~2050mb) groß ist ! Hast du mehr Ram zur Verfügung ? Falls ja dann dürfte es klappen :) Ansonsten würde ich mal die Größe des Arrays verringern :) MfG |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:47 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