AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Pointer - ein schwarzes Tuch

Ein Thema von gmc616 · begonnen am 13. Feb 2009 · letzter Beitrag vom 14. Feb 2009
Antwort Antwort
Seite 1 von 2  1 2      
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#1

Pointer - ein schwarzes Tuch

  Alt 13. Feb 2009, 14:05
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:
[...]
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 ;
Der Aufruf von CeFindAllDatabases funktioniert. Also scheinen ja Datenbank vorhanden zu sein, aber wie komme ich z.B. an den Namen (CeDBaseInfo.szDbaseName) rann ?

Könnt ihr mir Zeigen wie ich das bewerkstelligen muß.

1000 Dank schon mal im Voraus.

gmc

[edit=SirThornberry]Titel korrigiert - Mfg, SirThornberry[/edit]
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: Pionter - ein schwarzes Tuch

  Alt 13. Feb 2009, 14:14
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.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: Pionter - ein schwarzes Tuch

  Alt 13. Feb 2009, 14:54
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.

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.

Danke.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Pionter - ein schwarzes Tuch

  Alt 13. Feb 2009, 14:59
Und wie wäre es mit: "Verständsnisproblem bezüglich Pointern"?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
mr_emre_d
(Gast)

n/a Beiträge
 
#5

Re: Pionter - ein schwarzes Tuch

  Alt 13. Feb 2009, 15:04
Du musst es dereferenzieren

Ein ganz simples Pointer HowTo
Delphi-Quellcode:
{
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;
Ich garantiere keine 100% Korrektheit
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#6

Re: Pointer - ein schwarzes Tuch

  Alt 13. Feb 2009, 17:55
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:
API_funktion(pbytearr):bool dann solte das in Pascal/Delpi so gelöst werden:
Delphi-Quellcode:
var
  mybytearr : array[0..255] of byte;


if API_Funktion(@mybytearray) then ...
oder
Delphi-Quellcode:
type
  tmybytearray = array [0..255] of byte;
var
  mybytearray : tmybytearray;
  pmybytearray : ^tmybytearray;
 
...

  pmybytearray:=@mybytearray;
  if API_Funktion(pmybytearray) then ...
da gibt's bestimmt Empfehlungen wie's am Besten ist, aber die hab ich gerade nicht zur Hand.
Vielleicht ist in diesem Zusammenhang "Adresse" eine bessere Übersetzung als "Zeiger".
(Fehlinterpretatinen meinerseits bitte ich zu berichtigen)


Gruß
K-H
  Mit Zitat antworten Zitat
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#7

Re: Pointer - ein schwarzes Tuch

  Alt 13. Feb 2009, 18:18
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;
  Mit Zitat antworten Zitat
mr_emre_d
(Gast)

n/a Beiträge
 
#8

Re: Pointer - ein schwarzes Tuch

  Alt 13. Feb 2009, 20:13
Zitat von p80286:
API_funktion(pbytearr):bool
dann solte das in Pascal/Delpi so gelöst werden:
Delphi-Quellcode:
var
  mybytearr : array[0..255] of byte;
...
if API_Funktion(@mybytearray) then
Das ist genau das selbe Spielchen (z.B) mit
GetWindowText( hWnd, Buf ); buf = PChar --> Pointer zu (m ersten) Char (acter eines Strings, das Null-Terminiert ist)

dh. man könnte sich ein Buffer wie folgt definieren:
buf: Array[Byte] of Char; welches 256 Zeichen beinhalten kann und somit ->Buf entspricht !

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:
a. procedure ChangeInput(Input: Integer);
b. procedure ChangeInput(var Input: Integer);
b. procedure ChangeInput(Input: PInteger);
Bei a wird nur der Inhalt von "Input" kopiert und übergeben!
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

MfG
  Mit Zitat antworten Zitat
gmc616

Registriert seit: 25. Jun 2004
Ort: Jena
627 Beiträge
 
Delphi 10.3 Rio
 
#9

Re: Pointer - ein schwarzes Tuch

  Alt 13. Feb 2009, 23:16
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
New (ppFindData); "Ach, die Fehlermeldungen kennst! Gut!" dachte ich mir.
ppFindData weiß ja noch nicht, wohin er zeigen soll, damit das New weiß wieviel speicher es reservieren muß.

Also
Delphi-Quellcode:
procedure TFrom1.LeseDB();
var
  FindData : TCeDB_File_Data_Array;
  ppFindData: PCeDB_File_Data_Array;

// ...

ppFindData := @FindData;
New (ppFindData);
Nun stürzt das Programm bereits beim Aufruf der procedure LeseDB mit EStackOverflow ab.
Okay. Völlig Falsch.
Könnte wohl daran liegen, dass jetzt das New Speicher reservieren soll, der bereits reserviert ist. Oder? 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 ?

Aber eigentlich sollte das ganze doch auch ohne New funktionen, denn mit
ppFindData := @FindData; habe ich doch meinen Zeiger auf das FindData : TCeDB_File_Data_Array ??
Knallt aber ebenfalls mit EStackOverflow.

Jetzt bin ich der gleichen Stelle, an der ich heute Mittag schon war.
Und nu?

Die Hilfe zu New sagt:
Zitat:
Ist nicht genug Speicher für die dynamische Variable verfügbar, wird eine EOutOfMemory-Exception ausgelöst.
Hmm ... nächste Versuch:
GetMem (ppData,SizeOf (TCeDB_File_Data_Array)); EOutOfMemory - Zu wenig Arbeitsspeicher

Bin ich echt zu blöd dafür?

  Mit Zitat antworten Zitat
mr_emre_d
(Gast)

n/a Beiträge
 
#10

Re: Pointer - ein schwarzes Tuch

  Alt 14. Feb 2009, 00:51
Achtung - das ist nicht nur ein Pointer auf ne Variable sondern auf ein Array.

bsp:
Delphi-Quellcode:
type
  PByteArr = ^TByteArr;
  TByteArr = Array of Byte;

var
  X: PByteArr;
begin
  New( X );
  SetLength( X^, 10 );
  X^[0] := $FF;
  Dispose( X );
...
anderes, ähnliches bsp:
Delphi-Quellcode:
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]) );
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
( $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
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:19 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