![]() |
Wenn of object, dann knallts!!!
Hallo, ich habe folgende Funktion:
Delphi-Quellcode:
type
TGetLdapDomain = procedure(ldap: string) of object;
Delphi-Quellcode:
Wenn nun die CallBackFunktion of object ist, dann knallts... Wenn die CallBackFunktion nicht of Object mache, knallts nicht. Aber ich muss Sie of object machen, da sie zu einer Klasse gehören soll...
procedure GetLDAPDomains(CallBack: TGetLdapDomain);
var NSContainer : IADsContainer; Enum : IEnumVariant; hr : integer; varArr : OleVariant; lNumElements : ULONG; ADsItem : IADs; begin NSContainer := nil; Enum := nil; ADsGetObject('LDAP:', IID_IADsContainer, NSContainer); hr := ADsBuildEnumerator(NSContainer, Enum); while SUCCEEDED(hr) do begin hr := ADsEnumerateNext(Enum, 1, varArr, lNumElements); if (lNumElements<=0) then Break; IDispatch(varArr).QueryInterface(IID_IADs, ADsItem); CallBack(ADsItem.ADsPath); //ADsItem.Class_; end; //if Enum <> nil then // hr := ADsFreeEnumerator(Enum); VariantClear(varArr); end; (mit knallt es meine ich eine Access Violation) Ein weiteres Phänomen ist, wenn ich hr := ADsFreeEnumerator(Enum) wieder in den Code aufnehme, dann knallts so oder so... An was kanns liegen? Testet doch die Procedur mal bei euch.... Danke schon mal im Voraus. PS: Guten Appetit. |
Re: Wenn of object, dann knallts!!!
Meinst du vielleicht TObject?
|
Re: Wenn of object, dann knallts!!!
Wie rufst du denn GetLDAPDomains auf, bzw. wie ist die dort angegebene Prozedur definiert?
|
Re: Wenn of object, dann knallts!!!
Zitat:
Delphi-Quellcode:
die Message erscheint zwar noch korrekt, anschliessend gibts aber dann ne Access Violation...
procedure TForm1.getLdapDomain(domain: string);
begin showMessage(domain); end; ... GetLDAPDomains(getLdapDomain); |
Re: Wenn of object, dann knallts!!!
Müsstest du nicht erst ne Zuweisung machen?
Und: Wie soll die denn zu ner Klasse gehören? Ich blicke bei deinem Problem nicht ganz durch ^^ |
Re: Wenn of object, dann knallts!!!
Probiert doch die Funktion einfach mal aus, dann seht ihr schon was ich meine... Ich kanns selber fast nicht erklären...
Wenn ich z.B statt
Delphi-Quellcode:
dies mache:
procedure TForm1.getLdapDomain(domain: string);
begin showMessage(domain); end;
Delphi-Quellcode:
dann gehts auch, sobald ich aber dann auf die myList zugreiffen will, gibts ne böse Access Violation und ich weiss nicht woher die kommt!!!!
procedure TForm1.getLdapDomain(domain: string);
begin myList.Add(domain); end; |
Re: Wenn of object, dann knallts!!!
Zitat:
Naja, lass mal das "TForm1." weg und probier es dann nochmal mit globalen variablen. |
Re: Wenn of object, dann knallts!!!
Hmm... ist komisch. Ja es geht wenn die myList nicht TForm gehört, wie greiffe ich dann aber von einem andern Formular darauf zu?
Und das mit der CallBackFunction habe ich nur gemacht, weil es anders auch nicht geht. Die Procedure scheint nur dann keine Zugriffsverletzung zu geben, wenn ich keine listen oder variablen abfülle, die eben einer Klasse z.B. TForm1 angehören, egal ob mit Rückgabewert, var Patameter, Parameter oder eben CallBackFunction... irgendwo scheint etwas ganz Faul zu sein, aber was???? |
Re: Wenn of object, dann knallts!!!
Zitat:
Aber stell dir das doch mal so vor: Du versuchst von einem Objekt auf eine private Variable von einem anderem Objekt zuzugreifen. Das geht nicht, nur bei den Callbackfunktionen beanstandet der Kompiler das nicht. Soweit ich weiß hab ich damals eine globale Property von der Variable die ich in der CllBck-Mthd brauchte erstellt und dieser dann auch noch die Instanz des Objekts mitübergeben. So konnte ich dann in der Callback-Methode über diese Instanz auf die property zugreifen. edit: Also bei dir säh das dann so aus:
Delphi-Quellcode:
Kannst du ja mal testen. :wink:
procedure getLdapDomain(domain: string; const TheForm: TForm1);
begin TheForm.myList.Add(domain); end; Unschön, aber man hat wenigstens keine Unit-globale Variable. (nur den neuen Zugriff auf die eigentlich private Variable) Eine sauberere Alternative würde mich auch interessieren. :stupid: |
Re: Wenn of object, dann knallts!!!
Mal ne böse Frage..
Existiert das Objekt eigentlich, zu dem die Callback-Methode gehört? Grüße, Lutz |
Re: Wenn of object, dann knallts!!!
Zitat:
Ja, TForm1. |
Re: Wenn of object, dann knallts!!!
Ich kann mir es zwar nicht richtig vorstellen, aber spielt Dir die Referenzzählung von ADsItem vielleicht einen Streich? Kannst Du mal einen stinknormalen String an Deine Callback übergeben?
Lutz |
Re: Wenn of object, dann knallts!!!
Gleich nochmal ich. Besser noch, mal alles auskommentieren und nur die Callback mit einem String aufrufen.
Lutz |
Re: Wenn of object, dann knallts!!!
Zitat:
|
Re: Wenn of object, dann knallts!!!
Kannst Du mal den Aufruf für
GetLDAPDomains posten? Lutz |
Re: Wenn of object, dann knallts!!!
Das habe ich doch schon?!.. wie ich aber sehe, konzentriert ihr euch zu fest auf die Thematik Callback... Das Problem tritt aber auch anders auf,
deshalb habe ich die Methode jetzt umgeschrieben: Also nochmals von vorne... Ich habe diese Funktion:
Delphi-Quellcode:
Wenn ich im Programm z.B. die Funktion so aufrufe:
function GetLDAPDomain: String;
var NSContainer : IADsContainer; Enum : IEnumVariant; hr : integer; varArr : OleVariant; lNumElements : ULONG; ADsItem : IADs; begin NSContainer := nil; Enum := nil; ADsGetObject( 'LDAP:', IID_IADsContainer, NSContainer); hr := ADsBuildEnumerator(NSContainer, Enum); while SUCCEEDED(hr) do begin hr := ADsEnumerateNext(Enum, 1, varArr, lNumElements); if (lNumElements<=0) then Break; IDispatch(varArr).QueryInterface(IID_IADs, ADsItem); result := result + ADsItem.ADsPath + #13; //ADsItem.Class_; end; end; public {von TForm1} myVar: String;
Delphi-Quellcode:
Sobald ich myVar direkt in FormCreate deklariere, oder ausserhalb der Klasse TForm, dann gehts... so habe ich aber von anderen Forms keinen Zugriff,,, und überhaupt, wieso sollte das ein Problem sein so wie ich es mache=????
procedure TForm1.FormCreate(Sender: TObject);
begin // es kracht schon so myVar := GetLDAPDomain; end; |
Re: Wenn of object, dann knallts!!!
Dann hast Du uns auf eine falsche Fährte geführt..
Ich sehe eine Reihe von potentiellen Fehlerquellen, die ich gern ausschließen würde: 1. erste Zeile: Result := ''; 2. ADsGetObject liefert ein S_OK zurück, bitte auswerten 3. bei den anderen Funktionen bitte auch Rückgabewert auswerten Lutz |
Re: Wenn of object, dann knallts!!!
Erstmal sorry für die Irreführung...
Hab die Funktion nun ein wenig angepasst:
Delphi-Quellcode:
geht trotzdem nicht. Komisch ist ja, dass die Funktion das erwartete Resultat zurückgibt, wenn das result allerdings in eine Variable von einer Klasse gespeichert werden soll, gehts nicht. Bei einer Prozedur Variable klappts ja prima...
function GetLDAPDomain: String;
var NSContainer : IADsContainer; Enum : IEnumVariant; hr : integer; varArr : OleVariant; lNumElements : ULONG; ADsItem : IADs; begin Result := ''; NSContainer := nil; Enum := nil; if ADsGetObject( 'LDAP:', IID_IADsContainer, NSContainer) = S_OK then begin hr := ADsBuildEnumerator(NSContainer, Enum); while SUCCEEDED(hr) do begin hr := ADsEnumerateNext(Enum, 1, varArr, lNumElements); if (lNumElements<=0) then Break; if IDispatch(varArr).QueryInterface(IID_IADs, ADsItem) = S_OK then result := result + ADsItem.ADsPath + #13; end; end; end; ich kreigs nicht raus?! >> Ich würd auch gerne
Delphi-Quellcode:
verwenden, doch dann krachts auch beim speichern in eine Prozedurvariable... ??!?
if Enum <> nil then
hr := ADsFreeEnumerator(Enum); VariantClear(varArr); |
Re: Wenn of object, dann knallts!!!
Bei mir läuft's ohne Fehler durch. Allerdings ist bei mir lNumElements 0. Damit reduziert sich der Fehler auf die beiden Zeilen
Delphi-Quellcode:
Lutz
if IDispatch(varArr).QueryInterface(IID_IADs, ADsItem) = S_OK then
result := result + ADsItem.ADsPath + #13; [edit=mkinzler]Code-Tag durch Delphi-Tag ersetzt Mfg, mkinzler[/edit] |
Re: Wenn of object, dann knallts!!!
Hmmm... Hab mir eine DummyFunktion gebastelt:
Delphi-Quellcode:
und habe dabei festgestellt: Das Problem existiert auch so!
function test: String;
var NSContainer : IADsContainer; begin result := 'test'; NSContainer := nil; ADsGetObject( 'LDAP:', IID_IADsContainer, NSContainer); then Du hast es bei dir getestet? -> hast du auch versucht den Rückgabewert in eine public oder private Variable von TForm1 zu speichern? denn da krachts bei mir... |
Re: Wenn of object, dann knallts!!!
Sorry, es kracht doch. Abhilfe könnte aber vielleicht die Zeile
CoInitialize(nil); schaffen. Lutz |
Re: Wenn of object, dann knallts!!!
Ne, macht ja auch keinen Sinn... soweit ich weiss ist das schon initialisiert wenn on Create aufgerufen wird..
Also ich habs auch getestet, geht nicht. Ist aber schon krass komisch oder? |
Re: Wenn of object, dann knallts!!!
Sind Deine Funktionsprotypen stdcall oder safecall?
Lutz |
Re: Wenn of object, dann knallts!!!
ich verwende die units von agnisoft...
![]() safecall ! |
Re: Wenn of object, dann knallts!!!
Moin moin,
versuche doch mal bitte, Result erst nach dem "nil setzen" zu zuweisen, also so:
Delphi-Quellcode:
function GetLDAPDomain: String;
var NSContainer : IADsContainer; Enum : IEnumVariant; hr : HRESULT; varArr : OleVariant; lNumElements : ULONG; ADsItem : IADs; res : String; begin res := ''; NSContainer := nil; Enum := nil; try if ADsGetObject( 'LDAP:', IID_IADsContainer, NSContainer) = S_OK then begin hr := ADsBuildEnumerator(NSContainer, Enum); while SUCCEEDED(hr) do begin hr := ADsEnumerateNext(Enum, 1, varArr, lNumElements); if (lNumElements<=0) then Break; if IDispatch(varArr).QueryInterface(IID_IADs, ADsItem) = S_OK then res := res + ADsItem.ADsPath + #13; end; end; finally Enum := nil; NSContainer := nil; Result := res; end; end; |
Re: Wenn of object, dann knallts!!!
Langsam gehen mir die Ideen aus.
Bei Kosch habe ich einen abweichenden Funktionsprototypen gefunden:
Delphi-Quellcode:
Und dann noch diesen Artikel:
function ADsGetObject(lpszPathName: PWideChar; const riid: TGUID; out ppObject): HRESULT; Safecall;
![]() Ob das allerdings auch für Delphi2009 gilt? Lutz |
Re: Wenn of object, dann knallts!!!
dann bin ich ja wohl nicht der einzige mit diesem Problem. Hehe.
Danke euch beiden. Ich habe jetzt Wochenende und Zuhause hab ich leider weder D2009 noch meine Projektdaten, also kann ich wohl oder übel die Test erst nächsten Montag durchführen. Ich melde mich dann mit neuigkeiten, hats bei euch geklappt? lg und schönes Wochenende... #enemyleft |
Re: Wenn of object, dann knallts!!!
@x000x, @Delphianer
Das funktionert leider alles nichts, das Ergebnis ist immer dasselbe! Bringts denn niemand zum laufen? @x000x: Witzig ist ja, dass ich am Ende z.B. schreiben kann result := 'test'; und es passiert immer noch dasselbe Problem... Was ist hier bloss faul? Na, bringst Du es zum laufen? ;-) EDIT:// Ich bin echt am Ende meiner Nerven! Wenn ich das ganze nicht im FormCreate oder FormShow der MainForm habe, sondern in FormCreate einer anderen Form, dann klappts ohne Einwände. Nur wenn ich AdsFreeEnumerator Verwenden will tritt dann der Fehler noch auf. Ich schiebs jetzt mal auf Microsoft ab und begnüge mich mit dem Workaround. Obwohl ich damit eigentlich nicht ganz glücklich bin. Wenn also noch jemand eine Idee hat, bin ich immer noch sehr dankbar dafür. Habe übrigens im Internet viele ähnliche Threads gefunden, nur gelöst wurde er noch nie! |
AW: Wenn of object, dann knallts!!!
Hallo,
Entschuldigung wenn ich hier einen alten Thread aufwärme... Aber ich hatte eben das selbe Problem und ich glaube eine Lösung gefunden zu haben. Das Problem lag an der Deklaration der Funktion ADsGetObject():
Delphi-Quellcode:
Nach langem debuggen und pröbeln habe ich die deklaration abgeändert und siehe da: Keine AV mehr.
function ADsGetObject(lpszPathName:WideString; const riid:TGUID;
out ppObject):HRESULT; safecall; external 'activeds.dll';
Delphi-Quellcode:
stdcall ist das Schlüsselwort.
function ADsGetObject(lpszPathName:WideString; const riid:TGUID;
out ppObject):HRESULT; stdcall; external 'activeds.dll'; Ich hoffe es hilft, auch wenn der Threaderzeuger schon längs nicht mehr an diesem Projekt arbeiten sollte... |
AW: Wenn of object, dann knallts!!!
Mal zurück zur ersten Codeversion: Wie rufst du diese Funktion auf?
Zeig mir die Zeile! Edit: Och... Klar -.-' Bei Stdcall werden alle Parameter verkehrt herum auf den Stack gepusht, wohingegen bei der anderen Variante Register verwendet werden. Kehrt ADsGetObject zurück und beendet mit Ret X so poppt es wertvolle Register vom Stack, die es nicht darf (per SafeCall Deklaration), jedoch trotzdem tut (weil StdCall). Dadurch kommt es zu Problemen mit der Rücksprungsadresse die vor jeder Unterroutinenaufruf (SubProgramCall) auf den Stack gepusht wird... Ach ach... |
AW: Wenn of object, dann knallts!!!
Wenn ich das richtig verstehe, dann ist safecall hauptsächlich für COM wichtig. Für alle anderen Windows-API funktionen ist stdcall zu benutzen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:45 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