01. februar 2003 - 09:34Der er
3 kommentarer og 2 løsninger
Et par COM spg.
Jeg må indrømme at jeg er totalt newbie indenfor COM, men jeg skal have lavet et par allraound-komponenter, som både kan bruges fra ASP, VB, og andet, der normalt kan bruge COM.
1. Når en funktion, der er en del af komponentets interface, skal returnere et objekt, f.eks. en string, bruger man: myFunction([out, retval] BSTR* p_bstrOut) hvem er så ansvarlig for hhv. allokere og nedlægge objektet? Er det det kaldende progrm eller min klasse? Er det her korrekt? STDMETHODIMP CMyComponent::myFunction(BSTR *p_bstrOut) { *p_bstrOut = SysAllocString(OLECHAR("Bla bla bla")); } Eller vil det give anledning til memory leaks?
2. Når et argument sendes via. komponentets interface, f.eks. (igen) et objekt som string, og metoden er erklæret som: myFunction([in] BSTR bstrArg) er det så en kopi af variablen fra det kaldende program, eller er det en reference til den? Kan man selv bestemme det? Hvis ja, hvordan?
3. Jeg kan ikke finde dokumentation, der beskriver hvordan objekterne (komponenterne i DLL'en) bliver oprettet. Bliver de, og samtlige medlemsvariable oprettet som ny, isoleret kopi ved hvert kald til f.eks. CreateObject("MyDLL.MyComponent") eller overlever de statiske variable og kan principielt blive overskrevet fra forkellige programmer? f.eks. hvis jeg i CMyComponent erklærer en static char[200]; vil den så kun eksistere i en kopi hele DLL'ens levetid? Eller bliver der oprettet en kopi for hvert program, der bruger DLL'en, f.eks. en til inetinfo, en til mit VB program osv...?
4. Måske er det lidt naivt, men kan man, hvis der f.eks. ved kald til en eller anden klasses metode inde fra komponentet opstår en kritisk fejl, kalde en funktion, der enten får det kaldende program til at exit'e eller nedlægge dets instans af COM objektet og melde fejl?
Skriv gerne links til online litteratur/artikler om emnet som supplement til jeres svar :)
1. Ja, din kode ser ganske fornuftig ud, da det er klientens opgave at deallokere din string.
2.En BSTR er en LPWSTR som igen er en WCHAR* som igen er en WORD. Det vil sige at en BSTR er en pointer, og det er en reference til en streng som du får.
3. Hver gang der bliver oprettet en ny instance af dit COM Object, bliver der oprettet et nyt object og alle tilhørende membervariable. Statiske og globale variable kan jeg faktisk ikke lige huske lige nu, pinligt da jeg har brugt det en del for noget tid siden, men det er forholdsvis hurtigt lige at checke i en debugger ;-)
4. Nej. Men du kan kalde Error("Der skete en fejl"); og så returnere E_FAIL i stedet for S_OK. Så ved klienten at der er sket en fejl. For at kunne dette skal du sætte kryds i "Support IErrorInfo" når du opretter dit COM Object...
Tak for dit svar, tam. Jeg har godt nok fundet ud af de fleste ting ved eksperimenter, og så glemte jeg helt at jeg stadig havde et spg. åbent her. Men du svarer, så skal du naturligvis ha nogle point.
En anden del af svaret må være at man kan referenceoverføre input-variable f.eks. på denne her måde HRESULT myMethod([in] BSTR *p_bstrArg) - ved lige netop BSTR betyder det nok ikke så meget, da, som du selv siger det, BSTR er en pointer til et array af unsigned short.
Med statiske variable gælder der vist en regel med at de SKAL initialiseres i konstruktørens initialiseringslite. Mener at have set det som en "tip" i VC++ 6
Forresten angående punkt 2: der står ikke nævnt nogle steder om den string, der er reference til, i virkeligheden er en kopi af en variabel i klienten, eller om det er en kopi af referencen til den.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.