Toon posts:

[C++] ActiveX component in console app

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met de aansturing van een RFID scanner. De aansturing van deze scanner geschied via een ActiveX component. Echter, ik wil deze scanner aanspreken vanuit een console applicatie zonder gebruik te maken van MFC.
Als basis heb ik een voorbeeld MFC dialog based programma, welke gebruik maakt van het ActiveX component, genomen en dit proberen om te zetten.

Het gaat om de volgende functie uit de machine generated IDispatch wrapper class:
C++:
1
2
3
4
5
6
7
BOOL StringSelectCard(long p_iSelectMode, long p_iChipTypes, BSTR * p_sSN)
{
    BOOL result;
    static BYTE parms[] = VTS_I4 VTS_I4 VTS_PBSTR ;
    InvokeHelper(0x46, DISPATCH_METHOD, VT_BOOL, (void*)&result, parms, p_iSelectMode, p_iChipTypes, p_sSN);
    return result;
}


Na veel probeerseltjes en google ben ik tot het volgende resultaat gekomen (alleen relevante code).
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
    static CLSID const clsid
            = { 0xE8ED6166, 0xE84A, 0x11D3, { 0x93, 0x47, 0x0, 0x10, 0x5A, 0xF6, 0x2F, 0x28 } };

    VARIANT varOutput; 
    // create my ActiveX control 
    if(CreateComDispatch(clsid, &pInterface)) 
    { 
        HRESULT hRet; 
        DISPPARAMS callParams = { NULL, NULL, 0, 0 }; 
        VARIANT varOutput;

        int iParamCount = 3;
        BSTR *pbstrVal = new BSTR[1024]; // Yes, this will fit:P

        callParams.cArgs = iParamCount; 
        callParams.rgvarg = new VARIANTARG[iParamCount]; 
        
        //1st param
        callParams.rgvarg[0].vt = VT_I4; 
        callParams.rgvarg[0].iVal = 0x0;

        //2st param
        callParams.rgvarg[1].vt = VT_I4; 
        callParams.rgvarg[1].iVal = 0x8;

        //3st param
        VARIANT p_sSN;
        callParams.rgvarg[2].vt = VT_BSTR | VT_BYREF; 
        callParams.rgvarg[2].pbstrVal = pbstrVal;
        
        // invoke the method 
        unsigned int iArgErr; 

        hRet = pInterface->Invoke(0x45, 
                            IID_NULL, 
                            LOCALE_SYSTEM_DEFAULT, 
                            DISPATCH_METHOD, 
                            &callParams, 
                            &varOutput, 
                            NULL, 
                            &iArgErr); 

Het creeren van het COM component gaat goed, het aanroepen van een functie zonder parameters verloopt ook succesvol. Na het aanroepen van deze functie krijg ik echter een access violation. Mijn vermoede gaat uit naar de 3e parameter. Ik leid af uit de MFC based code dat de 3e parameter een pointer moet zijn naar een buffer waar het resultaat in gezet wordt. Deze string is niet heel groot en zou dus ook makkelijk in de 1024bytes moeten passen die ik hiervoor reserveer. Dankzij beperkte debugmogelijkheden (het programma draait op een tabled pc waar de scanner inzit en de ontwikkeling is op een andere workstation) en mijn beperkte kennis van ActiveX en MFC in het algemeen loop ik een beetje vast. MSDN en google bieden verder ook niet veel hulp op dit gebied. Hopelijk kan iemand mij in de goede richting helpen of een mogelijk alternatief voor deze methode aanwijzen.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Kun je de IDL van de interface achterhalen? Of andere documentatie?

Ik vermoed overigens dat de BSTR fout is. Jij hebt 1024 BSTRs, maar geen enkele van die strings heeft geheugen gealloceerd. Uit m'n hoofd is een BSTR een char* met bijzondere semantiek (niet simpelweg een NTBS). Een BSTR* is dus een char**. Google eens op SysAllocString?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 01-05 17:37

Gerco

Professional Newbie

Een BSTR ziet er ongeveer zo uit:
code:
1
2
3
4
struct BSTR { 
  long length; 
  WCHAR* str; 
}


Wat je nu hebt alloceert dus inderdaad geen geheugen voor de str member van die struct, maar alleen de struct zelf 1024 maal.

[ Voor 14% gewijzigd door Gerco op 16-08-2005 09:51 ]

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Topicstarter
MSalters schreef op dinsdag 16 augustus 2005 @ 00:43:
Kun je de IDL van de interface achterhalen? Of andere documentatie?

Ik vermoed overigens dat de BSTR fout is. Jij hebt 1024 BSTRs, maar geen enkele van die strings heeft geheugen gealloceerd. Uit m'n hoofd is een BSTR een char* met bijzondere semantiek (niet simpelweg een NTBS). Een BSTR* is dus een char**. Google eens op SysAllocString?
Helaas is er geen andere informatie, zoals de IDl, voorhanden. Een BSTR is inderdaad geen char*. Ik ging er gemakshalve vanuit dat dit een typedef zou zijn, tja stom :X
Als ik geheugen alloceer voor de BSTR 'werkt' het inderdaad wel. Ik krijg echter een DISP_E_TYPEMISMATCH, wat ik ook wel verwachtte omdat bij de MVC code de BSTR als pointer wordt meegegeven.
C++:
1
static BYTE parms[] = VTS_I4 VTS_I4 VTS_PBSTR ;

Maarja.. bij de 'non MFC' Invoke functie is het weer niet mogelijk om een pbstr als parameter mee te geven...
Nu weet ik weer waarom ik MFC en verwanten het liefst zoveel mogelijk mijd. :|