Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr? D2K9 (https://www.delphipraxis.net/132589-tat-und-form-var-param-fuzzt-aufeinmal-nicht-mehr-d2k9.html)

Alter Mann 15. Apr 2009 17:46


tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr? D2K9
 
Hi

und Entschuldigung für den Titel, mir ist nichts besseres eingefallen.

Ich muss an IDirectorySearch.ExecuteSearch ein Array of PWideChar übergeben,
bisher habe ich das so erledigt:
Delphi-Quellcode:

function DirectorySearch(Properties : Array of PWideChar;
                         SearchText : String;
                         Category  : String;
                          out Items : TStringList) : Boolean;
...
  hr := search.ExecuteSearch(StringToOleStr('(objectCategory=' + Category + ')'), @Properties[0], dwCount, ptrResult);
...
end;
Unter Delphi 7 lief die Sache durch, s.a. hier (Posting #7).

Unter Delphi 2009, kommt es zur besagten Fehlermeldung: Die Typen der tatsächlichen und formalen Parameter müssen übereintimmen.

Gibt es noch ein anderen Vorgehensweise oder einen Compilerschalter der die Überprüfung (kurzzeitig) ausschaltet?

Danke

mjustin 15. Apr 2009 17:51

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Zitat:

Zitat von Alter Mann
Unter Delphi 2009, kommt es zur besagten Fehlermeldung: Die Typen der tatsächlichen und formalen Parameter müssen übereintimmen

An welcher Stelle denn? Und welcher Parametertyp wird erwartet?

Etwas Fuzzy,

Alter Mann 15. Apr 2009 17:58

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
:thumb:

Kleine Frage, was muss ich übergeben? Ein Array of PWideChar und die Variable heißt dazu Properties;
Übergeben wird es so: @Properties[0].

Die aufzurufende Funktion ist so deklariert:
Delphi-Quellcode:
function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar;
         dwNumberAttributes: LongWord; out phSearchResult: THandle): HResult; stdcall;
Alles klar :wink:

mkinzler 15. Apr 2009 18:07

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Versuch mal
Delphi-Quellcode:
hr := search.ExecuteSearch(StringToOleStr('(objectCategory=' + Category + ')'), Properties[0], dwCount, ptrResult);

Alter Mann 15. Apr 2009 18:09

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Hi

gute Idee, werde es morgen probieren.

Danke

oki 15. Apr 2009 21:49

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Zur Not Caste es doch
Delphi-Quellcode:
  PWideChar(@Propeties[0])
Gruß oki

quendolineDD 15. Apr 2009 21:54

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Ich kenne es aus Funktionen aus der Win32Api, das zum Beispiel bei NetQueryDisplayInformation als letzter Parameter ein Pointer zu einem Array of Record gegeben sein muss.
Dann übergebe ich einen Pointer (Buf := nil) und bekomme dort dann die Adresse reingeschrieben. Kleines Beispiel
Delphi-Quellcode:
var
  User       : PNET_DISPLAY_USER;

[...]

  Buf := nil;
  Status := NetQueryDisplayInformation(PWideChar(Domain), 1, 0, 100, MAX_PREFERRED_LENGTH, @Ret, Buf);

[...]

User := Buf;
Dann kann ich nun über die Dereferenzierung auf die Daten zugreifen und für das nächste Element im Array inkrementiere ich einfach den Pointer.
Bei Arrays als Var-Parameter ist das doch eh so eine Sache.

Alter Mann 16. Apr 2009 07:07

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Moin, Moin

bisher geht es nicht, auch wenn die Tipps sich gut (lesen/anhören).

Lass ich das @-Zeichen weg, wird das Programm zwar compiliert, aber bei der Ausführung
kommt es dafür zu einer "Zugriffsverletzung im Module 'WLDAP32.DLL'".

Das Casting mit PWideChar(@Properties[0]) mag er nicht, da aus einer var-Variablen eine Konstante wird.

Und zu guter Letzt, da ich in 'Properties' Werte übergebe geht das mit der Pointer-Inkrementierung leider auch nicht.

Was bleibt, ist die Suche nach der Lösung.

Danke

mkinzler 16. Apr 2009 07:09

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Und wenn du aus dem Array einen #0 getrennten String machst ( c StringArray)?

oki 16. Apr 2009 07:25

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Zitat:

Zitat von Alter Mann
Das Casting mit PWideChar(@Properties[0]) mag er nicht, da aus einer var-Variablen eine Konstante wird.

Moin,

leider kann ich aktuell nicht sehen warum der Compiler beim casten bezüglich der Zuweisung meckert. Das Properties ein Var ist hab ich so nicht entdeckt. Wie steht es damit eine lokale Variable vom Typ PWideChar zu definieren und den Inhalt von Propertys da hinein zu kopieren. Dann kanns du deine Variable problemlos übergeben.

Das mit dem var hab ich trotzdem noch nicht gerafft.

Gruß oki

oki 16. Apr 2009 07:34

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Mal ne doofe Frage, wo und wie definierst du ptrResult?

Alter Mann 16. Apr 2009 07:45

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
@oki

siehe Link im ersten Beitrag.

oki 16. Apr 2009 07:49

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Zitat:

Zitat von Alter Mann
@oki

siehe Link im ersten Beitrag.

Ah klar, hatte ich übersehen.
Wie steht es mit der lokalen Variable PWideChar?

Vielleicht so?
Delphi-Quellcode:
...
var PProps : PWideChar;
...
  PProps := PWideChar(@Properties[0]);
  hr := search.ExecuteSearch(StringToOleStr('(objectCategory=' + Category + ')'), PProps, dwCount, ptrResult);

Alter Mann 16. Apr 2009 08:12

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Hi oki

Ich kann nicht erkennen worauf du hinaus willst.

Wie schon geschrieben, das Problem taucht erstmalig mit Delphi 2009 auf,
alle anderen Versionen(D5, D7, D2005, D2007) compilieren den Code 1a.

Oh, dazwischen gefunkt.

Habe es probiert; Ergebnis: "Zugriffsverletzung im Modul 'msvcrt.sll'".

Es scheint ein reines Delphi 2009 - Problem zu sein.

oki 16. Apr 2009 08:15

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Jo, dann bin ich am Ende. Kann das auch nicht überprüfen, da D2007. Macht mir aber etwas sorgen das Problem. Hab solche Konstrukte nie als Problem gesehen und relativ oft verwendet. Sollte mich dann erst mal mit D2009 zurückhalten :lol:

Gruß oki

Alter Mann 16. Apr 2009 11:44

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Mir ist da noch etwas aufgefallen.

Beim setzen der SearchPreference werden zu Abfangen eines Fehlers statische 'Array of WideChar' verwendet
Delphi-Quellcode:
var
...
  szErr    : array[0..255] of WideChar;
  szName   : array[0..255] of WideChar;
  idx      : Integer;
  found    : Boolean;
begin
  if SUCCEEDED(ADsGetObject(edtADsPath.Text, IDirectorySearch, Search)) then
  begin
    try
      opt.dwSearchPref  := ADS_SEARCHPREF_SEARCH_SCOPE;
      opt.vValue.dwType := ADSTYPE_INTEGER;
      opt.vValue.__MIDL_0010.Integer := ADS_SCOPE_SUBTREE;
      if not SUCCEEDED(search.SetSearchPreference(opt, 1)) then
      begin
        ADsGetLastError(dwErr, @szErr[0], 254, @szName[0], 254); // <- hier klappt es
        ShowMessage(WideCharToString(szErr));
        Result := False;
        Exit;
      end;
...
liegt es hier
Delphi-Quellcode:
hr := search.ExecuteSearch(StringToOleStr('(objectCategory=' + Category + ')'), @Properties[0], dwCount, ptrResult);
nun daran, das ein dynamisches Array ist, oder aber ein PWideChar?

Klaus01 16. Apr 2009 12:03

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
.. ist es nicht so,
dass bei einem statischen Array @Array[0] die Adresse des
ersten Elementes liefert.

Ein dynamisches Array wird aber schon durch seine Adresse
repräsentiert.

Sollte es dann nicht reichen, es so zu übergeben?
Delphi-Quellcode:
hr := search.ExecuteSearch(StringToOleStr('(objectCategory=' + Category + ')'), Properties, dwCount, ptrResult);
Grüße
Klaus

oki 16. Apr 2009 12:15

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Nun ja,

mir ist nicht alles klar was du gepostet hast. Das liegt aber wohl eher daran, dass ich mit diesem Konstrukt noch nicht gearbeitet habe.

Grundsätzlich bin ich aber der Meinung, dass du einen Zeiger auf WideChars übergeben musst. Imho gestaltet sich das bei dynamischen Arrays so:
Delphi-Quellcode:
  Propertes[0]
Bei statischen so:
Delphi-Quellcode:
  @Propertys[0]
Ich glaube mich duster daran erinnern zu können, dass dynamische Arrays Zeiger beinhalten. Irgentwie bin ich mir jetzt aber auch nicht mehr sicher. :gruebel:

Ein Array of WideChar sollte aber wie in deinem Fall nur 256 WideChar-Zeichen enthalten. Somit zeigt imho Properties[1] nicht auf den zweiten Namen, sondern auf das zweite Zeichen.

Das sollte aber alles in Bezug auf den Aufruf egal sein. Entscheidend ist, dass ein Zeiger auf WideChars übergeben wird. Das sollte in deinem Fall mit @Properties[0] korrekt sein.

Wieviele Namen übergibst du denn? Vielleicht fehlt die #0 hinter jedem Namen wenn es mehrere sind oder die Länge stimmt nicht? Ich denke mal, es klappt bei ADsGetLastError, weil szName lokal als Variable definiert ist und die Funktion szName füllt.
Ist denn der Rückgabewert von szName dein Properties?

Was steht denn in Properties drin? Vielleicht kämpfst du ja auch mit zwei Problemen,
1. Richtige Übergabe des Parameters,
2. fehlerhafter Eintrag im Parameter.

Was steht bei dir in dwNumberAttributes für ein Wert? Passt der zur Anzahl der Atribute? Nicht dass hier versehentlich die Anzahl der Zeichen übergeben wird?

Gruß oki

Alter Mann 16. Apr 2009 12:21

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Hi @oki

Wenn ich dieses Problem hätte, wäre es keins.

Der Compiler bleibt an der Stelle @Properties[0] stehen und mault rum:
'Die tatsächlichen und formalen Parameter stimmen nicht überein'.

Das mit den 'Array[0..255] of WideChar' war nur ein Gedankengang, da diese Stelle klaglos
durchgeht.

OK?

oki 16. Apr 2009 12:34

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Ja klar,

der Punkt ist aber, dass Delphi 2009 nicht damit klar kommt, dass ein PWideChar erwartet wird und du den @-Operator verwendest. Somit sehe ich das so, dass du hier wohl zwingend den Typ benutzen musst der angegeben ist. Warum das bei deinem letzten Beispiel klappt ignoriere ich jetzt mal geflissentlich :mrgreen: .

Ich sehe da auf dieses Problem bezogen zwei Wege.
1. Ein Type-Caste
2. Verwendung einer lokalen Variable

Der Type-Caste scheint ja nicht zu funzen. Die Verwendung einer lokalen Variable führt zu einer Exception. Damit kommt aber der Compiler klar. Also muss was mit dem Inhalt nicht stimmen. Entweder das einfache Casten auf PWideChar liefert Müll oder der Inhalt ist von Vornherein Müll (oder die Anzahl der Elemente passt nicht oder ...).

Deshalb meine Frage, was in Properties denn drin steht.

Leg doch mal eine lokale Variable wie in deinem letzten Beispiel an und kopiere die Properties dort rein.
Delphi-Quellcode:
var szPropertys : Array [0..255] of WideChar;

...
  szProperties := Properties;
  hr := search.ExecuteSearch(StringToOleStr('(objectCategory=' + Category + ')'), @szProperties[0], dwCount, ptrResult);
Wie gesagt, da mein Beispiel mit PWideChar als lokale Variable vom Compiler geschluckt wurde kann die nachfolgende Exzeption auch daran liegen, dass der Inhalt von Properties danach nicht wirklich übergeben wurde.

Was ist eigentlich, wenn du deinen Funktionskopf so veränderst, dass Properties als var-Parameter oder gleich als PWideChar übergeben wird?

Gruß Oki

Alter Mann 16. Apr 2009 16:20

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
So, so


@oki danke für die Hartnäckigkeit.

Ich hatte den Code mal dahin gehend geändert, aber danach kam die bekante Zugriffsverletzung in WLDAP32.dll.

Also noch mal ein Blick in das SDK:

Zitat:

HRESULT ExecuteSearch(
LPWSTR pszSearchFilter,
LPWSTR* pAttributeNames,
DWORD dwNumberAttributes,
PADS_SEARCH_HANDLE phSearchHandle
);

Parameters
pszSearchFilter
[in] A search filter string in LDAP format, such as "(objectClass=user)".
pAttributeNames
[in] An array of attribute names for which data is requested. If NULL, all attributes are requested and dwNumberAttributes must be -1.
dwNumberAttributes
[in] The size of the pAttributeNames array. If -1, all attributes are requested and pAttributeNames must be NULL.
phSearchHandle
[out] The address of a method-allocated handle to the search context. The caller passes this handle to other methods of IDirectorySearch to examine the search result. If NULL, the search cannot be executed.
Dort steht nun mal nicht [in/out] LPWSTR* pAttributeNames sondern nur LPWSTR* pAttributeNames.

Also liegt (mal wieder) am falschen Typlib-Import.

Delphi-Quellcode:
    function ExecuteSearch(pszSearchFilter: PWideChar; var pAttributeNames: PWideChar;
                           dwNumberAttributes: LongWord; out phSearchResult: Pointer): HResult; stdcall;
ist einfach verkehrt. Es muss richtig so aussehen:
Delphi-Quellcode:
    function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar;
                           dwNumberAttributes: LongWord; out phSearchResult: THandle): HResult; stdcall;
Warum das nun so ist, keine Ahnung, war aber schon mit D7 so.

Danke.

oki 16. Apr 2009 16:35

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Hi Alter Mann,

1. funzt es jetzt also?

2. Du hattest in einem vorherigen Post diese Implementation vorgestellt:
Delphi-Quellcode:
function ExecuteSearch(pszSearchFilter: PWideChar; pAttributeNames: PWideChar;
                           dwNumberAttributes: LongWord; out phSearchResult: THandle): HResult; stdcall;
Wo kommt den jetzt die Implementation mit dem var-Parameter her? Ich hatte selber nicht nachgeschaut wie Delphi die implementiert. Oder hast du die Implementation selber vorgenommen?

Gruß oki

Alter Mann 16. Apr 2009 16:44

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
:oops:
Ich habe die ADS-Umgebung in VMs und dort den Fehler gemacht die 'ActiveDS_TLB' neu zu importieren.
Dabei hatte ich doch schon eine 'bereinigte' Version. :wall: :wall:

Also nichts für Ungut, werde in Zukunft vorher besser prüfen welche Version von welcher Unit benutzt wird.

Für die Ressourcenverschwendung bitte ich um Entschuldigung.

Alter Mann

oki 16. Apr 2009 17:43

Re: tat. und form. Var-Param. - fuzzt aufeinmal nicht mehr?
 
Zitat:

Zitat von Alter Mann
:oops:
Für die Ressourcenverschwendung bitte ich um Entschuldigung.
Alter Mann

Da bist du nicht alleine :mrgreen:
Und das mit dem prüfen sagt sich immer so leicht. Geht den Menschen wie den Leuten. hauptsache das Problem ist gelöst.

Dann noch einen schönen Abend,

Gruß oki


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:41 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