IDispatch\Invoke, wer gibt speicher frei?

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

IDispatch\Invoke, wer gibt speicher frei?

Beitrag 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
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: IDispatch\Invoke, wer gibt speicher frei?

Beitrag 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()
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: IDispatch\Invoke, wer gibt speicher frei?

Beitrag 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.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7028
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: IDispatch\Invoke, wer gibt speicher frei?

Beitrag von STARGÅTE »

Wie wäre es mit ClearStructure() ?
das "säubert" die Strings in solchen Speichern und dann kannst du Free'n
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: IDispatch\Invoke, wer gibt speicher frei?

Beitrag 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.
Benutzeravatar
Josh
Beiträge: 1028
Registriert: 04.08.2009 17:24

Re: IDispatch\Invoke, wer gibt speicher frei?

Beitrag 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:
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: IDispatch\Invoke, wer gibt speicher frei?

Beitrag 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.
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: IDispatch\Invoke, wer gibt speicher frei?

Beitrag 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
Antworten