Kopieren von COM-Objekten
-
Hi Leute,
Ich hab zwar schonmal gefragt, aber ich frag einfach nochmal, weil ich eine neue Erkenntnis gewonnen hab
Ich habe es so probiert:std::vector<IComObject*> vec; HRESULT MyDialog::OnSpecificEventReceivec(IComObject *pObject) { IComObject *pMyObject; CoCreateInstance(CLSID_ComObject,NULL,CLSCTX_INPROC_SERVER, IID_IComObject,(void**)&pMyObject); *pMyObject = *pObject; vec.push_back(pMyObject); pObject->Release(); }
Es tut. Aber ist das ok? Oder kann es sein, dass es dann irgendwann Komplikationen gibt? Steig bei COM noch net so 100% durch
-
dEUs schrieb:
Es tut. Aber ist das ok?
Nein, ist es nicht! Wieso erzeugst Du überhaupt ein neues Objekt? Zum Aufbewahren von Objekten verwendet man jedenfalls AddRef:
HRESULT MyDialog::OnSpecificEventReceivec(IComObject *pObject) { IComObject *pMyObject; pMyObject = pObject; pMyObject->AddRef(); vec.push_back(pMyObject); }
Das ergibt zwei gültige Objekte: Das Original bleibt gültig, der Aufrufer kann es weiter verwenden. Das Objekt im Vector ist ebenfalls gültig. Du mußt aber beide mit Release freigeben, wenn Du sie nicht mehr benötigst.
-
Das hat man mir beim letzten Mal auch schon empfohlen, leider tut das nicht
-
dEUs schrieb:
Das hat man mir beim letzten Mal auch schon empfohlen, leider tut das nicht
Dann machst Du an anderer Stelle noch einen Fehler.
-
Hm, mal schauen. Ich versuche es nochmals.
-
[quote="dEUs"]
*pMyObject = *pObject;
Oder liegt das eventuell an den Sternchen, daß das bei Dir nie funktioniert? Bis eben bin ich eigentlich doch davon ausgegangen, daß sich der Fehler beim Copy&Paste eingeschlichen hat, aber man kann ja nie wissen ...
-
Das mit den Sternchen war schon Absicht. Ich will damit erreichen, dass eben nicht die Speicheradresse kopiert wird, sondern der Inhalt. Stichwort: Dereferenzierungsoperator ...
-
Die Frage bleibt: Hast Du diesen Unfug sonst auch gemacht? Vergleiche das ruhig mal mit meiner Version ...
-
Ahso, ne, die Idee kam mir grad vorhin erst
-
Jetzt muß ich es doch noch loswerden, sorry:
Stichwort: Anfängerfehler! :p
-
Gemein!
Aber dann erklär ihn mir wenigstens. Mit "normalen" Objekten würde soetwas auch tun. Wieso mit COM-Objekten nicht?Und:
Funktioniert das auch:CComPtr<IComObject> MyObject; pObject->AddRef(); MyObject = pObject;
-
dEUs schrieb:
Mit "normalen" Objekten würde soetwas auch tun. Wieso mit COM-Objekten nicht?
Mit normalen Objekten geht das? Das will ich mal probieren:
struct A { A() : m_a(1) { } ~A() { } private: int m_a; }; void OnSpecificEventReceivec(A* a) { A* tmp; *tmp = *a; }
Bei mir knallt das. Und das muß es auch! Der Pointer tmp zeigt doch ins Leere. Und irgendwie verstehe ich auch gar nicht, welchen Inhalt Du kopieren willst. An die Daten, die das Objekt beispielweise verwendet, kommst Du doch sowieso nicht ran.
Funktioniert das auch: C/C++ Code: CComPtr<IComObject> MyObject; pObject->AddRef(); MyObject = pObject;
Keine Ahnung, ob das funktioniert. Wenn der operator= intern nicht AddRef aufruft, dann ja. Der Lesebarkeit ist es aber zuträglich, wenn Du AddRef auf die Kopie ausführst und nicht auf das Original.
-
Genau deswegen (dass tmp nicht ins leere zeigt) habe ich CoCreateInstance aufgerufen. Und wieso soll das nicht funktionieren? Ist doch genau das selbe dann, wie:
struct A { A() : m_a(1) { } ~A() { } private: int m_a; }; void OnSpecificEventReceivec(A* a) { A tmp; tmp = *a; }
Und das sollte tun. Oder bin ich jetzt doof?
Wenn du jetzt sagt, das tut nicht, dann ists ok, weil mich das momentan eh net so sonderlich interessiert
Das mit dem AddRef tut übrigens nicht, egal, auf welches Objekt ich es anwende.
Ich versuch dir mal zu erklären, was ich mach:
Ich habe ein Event registriert. Über dieses Event bekomme ich Zeiger auf sogenannte Stroke-Objekte. Genau diese Stroke-Objekte möchte ich speichern. Jedes Stroke-Objekt hat einen Member, welches auf ein übergeordnetes "Ink"-Objekt zeigt. Dieses Inkobjekt besitzt eine Funktion: DeleteStrokes. So, und sobald ich diese Funktion aufgerufen habe sind alle meine (mit AddRef!) gespeicherten Zeiger ungültig. Wenn ich auf solch einen Zeiger eine Funktion aufrufe gibt mir diese einen Fehler zurück:
/*** TPC_E_INVALID_STROKE 0x80040222 -2147220958 * The stroke object was deleted. */ #define TPC_E_INVALID_STROKE MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 0x222)
Und genau deswegen möchte ich eine vollwertige Kopie.
-
dEUs schrieb:
So, und sobald ich diese Funktion aufgerufen habe sind alle meine (mit AddRef!) gespeicherten Zeiger ungültig.
Nope! Der Zeiger bleibt gültig und muß mit einem Release freigegeben werden. Lediglich die aufgerufene Methode schlägt fehl. Und das hat, wie gesagt, nichts mit der Gültigkeit des Pointers zu tun.
Eine Kopie, wie Du sie Dir vorstellst, kannst Du gar nicht erstellen. Wenn das Parent alle seine Childs in diesen unerwünschten Status versetzt, dann ist das so. Da bleibt Dir nur das Erzeugen eines völlig neuen Objekts, vermutlich auch mit einem unabhängigem Parent.
-
Seufz
Dann probier ich, ob ich das auch ohne diese DeleteStrokes-Methode hinbekomm, weil ein unabhängiges Stroke-Objekt kann ich nicht erzeugen: Es ist keine CLSID definiert ...