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:
Na veel probeerseltjes en google ben ik tot het volgende resultaat gekomen (alleen relevante code).
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.
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.