Seite 1 von 1

IDispatch\Invoke, wer gibt speicher frei?

Verfasst: 20.01.2010 19:54
von Josh
vielleicht habe ich auch nur einen denkfehler. hier ist es ein bisschen schwer ein lauffähiges beispiel zu bringen, aber ich glaube der code ist auch so klar:

Code: Alles auswählen

define *vReault.VARIANT
..........
..........
..........
*vResult = AllocateMemory(SizeOf(VARIANT))

*IDisp\Invoke(DispId, ?IID_NULL, #LOCALE_USER_DEFAULT, #DISPATCH_METHOD, @DispPar, *vResult, 0, 0)
;hier irgendwas mit *vResult machen

FreeMemory(*vResult)
wenn die methode einen string zurück gibt, dann steht in *vResult\vt als typ 8 und in *vResult\bstrVal steht ein pointer auf den bstring. dass ich meine speicherreservierung wieder frei gebe, ist klar. aber wer gibt eigentlich den reservierten speicher des bstrings frei? msdn lässt sich darüber nicht aus.


verschoben >> API
- Kaeru fecit

Re: IDispatch\Invoke, wer gibt speicher frei?

Verfasst: 20.01.2010 20:17
von ts-soft
Warum

Code: Alles auswählen

define *vReault.VARIANT
statt

Code: Alles auswählen

define vReault.VARIANT
?
Sparste Dir das freigeben des Speichers.

Ansonsten wird der Speicher des Objektes von diesem verwaltet, lediglich das Objekt mußt Du irgendwann
wieder freigeben, meist mit realease()

Re: IDispatch\Invoke, wer gibt speicher frei?

Verfasst: 20.01.2010 20:41
von Josh
hab ich mit speicherreservierung gemacht, weil ich das ergebnis über die procedurgrenze hinaus brauche und erst dort den speicher frei geben.

der gedanke mit dem freigeben von dem bstring ist mir deshalb gekommen, weil ich zum testen mal eine funktion in dem anwendungsprogramm gewählt habe, wo ich einfach das windows standarddialogfeld zum auswählen eines pfades angezeigt bekomme. als rückgabewert bekomme ich im bstring dann den pfad. wer den speicher des bstrings wieder freigeben soll, ist mir immer noch vollkommen unklar.

Re: IDispatch\Invoke, wer gibt speicher frei?

Verfasst: 20.01.2010 20:52
von STARGÅTE
Wie wäre es mit ClearStructure() ?
das "säubert" die Strings in solchen Speichern und dann kannst du Free'n

Re: IDispatch\Invoke, wer gibt speicher frei?

Verfasst: 20.01.2010 20:54
von freak
Es ist deine VARIANT Struktur, also must auch du das was drin steht freigeben, egal wo es herkommt. :D
Generell ist es so in COM das die Rückgaben eines Aufrufs immer vom Aufrufer frei zu geben sind falls nicht anders dokumentiert.

VariantClear_() ist hierfür ein nützlicher Helfer.

STARGÅTE:
ClearStructure() gibt nur PB Strings frei, keine API Typen.

Re: IDispatch\Invoke, wer gibt speicher frei?

Verfasst: 20.01.2010 21:01
von Josh
freak hat geschrieben:Es ist deine VARIANT Struktur, also must auch du das was drin steht freigeben, egal wo es herkommt. :D
Generell ist es so in COM das die Rückgaben eines Aufrufs immer vom Aufrufer frei zu geben sind falls nicht anders dokumentiert.

VariantClear_() ist hierfür ein nützlicher Helfer.
danke für die klare aussage :praise: :praise: :praise:

Re: IDispatch\Invoke, wer gibt speicher frei?

Verfasst: 20.01.2010 21:03
von ts-soft
freak hat geschrieben:VariantClear_() ist hierfür ein nützlicher Helfer.
Gut zu Wissen, aber wurde VariantInit_() vom irgendwem ausgeführt oder ist dies noch Extra
erforderlich? Wenn ich die MSDN richtig verstehe (english und ich :mrgreen: ) muß dieses geschehen
sein.

Re: IDispatch\Invoke, wer gibt speicher frei?

Verfasst: 20.01.2010 21:25
von freak
VariantInit_() setzt die Struktur auf VT_EMPTY, welches den Wert 0 hat. Da PB alle Strukturen (und Speicher) mit 0 initialisiert ist das also nicht mehr nötig. VariantInit_() wird gebraucht wenn der Speicher vorher unbestimmten Inhalt hat (wie zum Beispiel Variablen in C) damit besagter Inhalt nicht fälschlicherweise zum Beispiel als Stringpointer interpretiert wird.

Weitere nützliche Funktionen für VARIANTs sind übrigens VariantCopy_() und VariantChangeType_(). Mit letzterer kann man zum Beispiel die VARIANT Struktur in einen String umwandeln egal was für einen Typ sie vorher hatte, was für unbekannte Werte ganz praktisch ist:

Code: Alles auswählen

; Wandelt die VARIANT Struktur in einen String um und gibt den Inhalt frei
;
Procedure.s VariantString(*var.VARIANT)
  Protected Result.s = ""

  If VariantChangeType_(*var, *var, 0, #VT_BSTR) = #S_OK
    Result = PeekS(*var\bstrVal, -1, #PB_Unicode)
    VariantClear_(*var)
  EndIf

  ProcedureReturn Result
EndProcedure