Bonjour,
Je travaille actuellement sur la programmation d'un robot industriel qui s'interface avec l'ordinateur avec un objet COM. Et bien sûr je dois m'interfacer en langage C alors que seul le cas de JavaScript est documenté par le constructeur...
Je ne connais pas les objets COM, j'ai tout appris dessus via quelques liens :
http://www.codeproject.com/Articles/...COM-in-plain-C
http://www.codeguru.com/cpp/i-n/iepr...pplication.htm
http://ccc.panitzco.com/mpanitz/COM_...InCInProc.html
J'ai beau copier, analyser et réimplémenter les codes d'exemples, cela ne suffit pas.
En fait, j'arrive à obtenir l'objet mais je ne parviens pas à utiliser les fonctionnalités qu'il est censé proposé, soit cela plante (genre la console crashe), soit j'ai un code d'erreur type 0xC0000005 qui est normalement une violation d'accès (je précise que je suis sous Windows XP SP3 avec les droits d'administrateur).
Et cela fait plusieurs jours que je patine sans trouver une piste.
Voici le code source en entier (je n'ai pas de .h volontairement dans un premier temps et les fonctions en commentaires font planter l'exécution tandis que les autres renvoient une erreur) :
Je poste en supplément les informations sur l'objet COM dont il est question.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161 #include <windows.h> #include <objbase.h> #include <initguid.h> #include <stdio.h> #include <OleAuto.h> #include <wchar.h> #include <string.h> #define INTERFACE Rob5x //92507B34-D92D-4F8C-967E-6C5166C0F1F6 DEFINE_GUID(IID_Rob5x, 0x92507b34, 0xd92d, 0x4f8c, 0x96, 0x7e, 0x6c, 0x51, 0x66, 0xc0, 0xf1, 0xf6); //5DD00CD6-E135-4799-A83F-62F06688700F DEFINE_GUID(CLSID_Rob5x, 0x5dd00cd6, 0xe135, 0x4799, 0xa8, 0x3f, 0x62, 0xf0, 0x66, 0x88, 0x70, 0x0f); DECLARE_INTERFACE_ (INTERFACE, IDispatch) { /* Implémentation de la classe IUnknown */ STDMETHOD (QueryInterface) (THIS_ GUID *, void **) PURE; STDMETHOD_ (ULONG, AddRef) (THIS) PURE; STDMETHOD_ (ULONG, Release) (THIS) PURE; /* De même pour la classe IDispatch */ STDMETHOD_ (HRESULT, GetTypeInfoCount) (THIS_ UINT *) PURE; STDMETHOD_ (HRESULT, GetTypeInfo) (THIS_ UINT, LCID, ITypeInfo **) PURE; STDMETHOD_ (HRESULT, GetIDsOfNames) (THIS_ REFIID, LPOLESTR *, UINT, LCID, DISPID *) PURE; STDMETHOD_ (HRESULT, Invoke) (THIS_ DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *) PURE; /* Méthodes de la classe spécifique au robot */ STDMETHOD_ (ULONG, CloseComm) (THIS) PURE; STDMETHOD_ (ULONG, Energize) (THIS_ ULONG) PURE; STDMETHOD_ (BSTR, GetErrorInfo) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, GetCurrentPosition) (THIS_ VARIANT) PURE; STDMETHOD_ (ULONG, GetString) (THIS_ VARIANT) PURE; STDMETHOD_ (ULONG, GotoHome) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, GotoPoint) (THIS_ BSTR, ULONG) PURE; STDMETHOD_ (ULONG, GotoPosition) (THIS_ long, long, long, long, long, ULONG) PURE; STDMETHOD_ (ULONG, GotoUserPosition) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, InitRobot) (THIS) PURE; STDMETHOD_ (ULONG, MemPointPosition) (THIS_ long, long, long, long, long, BSTR) PURE; STDMETHOD_ (ULONG, Move) (THIS_ ULONG, ULONG, ULONG, ULONG) PURE; STDMETHOD_ (ULONG, OpenComm) (THIS_ BSTR) PURE; STDMETHOD_ (ULONG, RestoreUserDefaultPosition) (THIS) PURE; STDMETHOD_ (ULONG, SendString) (THIS_ BSTR) PURE; STDMETHOD_ (ULONG, SetSpeed) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, SetUserPosition) (THIS_ long, long, long, long, long) PURE; STDMETHOD_ (ULONG, Wait) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, SetLimits) (THIS_ long, long, long, long, long) PURE; STDMETHOD_ (ULONG, RestoreDefaultLimits) (THIS) PURE; STDMETHOD_ (ULONG, GetLimits) (THIS_ VARIANT) PURE; STDMETHOD_ (ULONG, SetToolParam) (THIS) PURE; STDMETHOD_ (LONG, GetToolParam) (THIS) PURE; STDMETHOD_ (ULONG, Align) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, GetVacuum) (THIS_ VARIANT) PURE; STDMETHOD_ (ULONG, Pump) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, Valve) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, OpenManualBox) (THIS) PURE; STDMETHOD_ (ULONG, GetSpeed) (THIS_ VARIANT) PURE; STDMETHOD_ (ULONG, WaitForManualBoxEnd) (THIS) PURE; STDMETHOD_ (BSTR, GetSerialNumber) (THIS) PURE; STDMETHOD_ (ULONG, GetUserPosition) (THIS_ VARIANT) PURE; STDMETHOD_ (ULONG, Calibrate) (THIS_ long) PURE; STDMETHOD_ (ULONG, GetSpeedStatus) (THIS) PURE; STDMETHOD_ (ULONG, GetSpeedNum) (THIS) PURE; STDMETHOD_ (ULONG, GetCurrentPositionStatus) (THIS) PURE; STDMETHOD_ (BSTR, GetCurrentPositionStr) (THIS) PURE; STDMETHOD_ (ULONG, GetLimitsStatus) (THIS) PURE; STDMETHOD_ (BSTR, GetLimitsStr) (THIS) PURE; STDMETHOD_ (ULONG, GetVacuumStatus) (THIS) PURE; STDMETHOD_ (ULONG, GetVacuumNum) (THIS) PURE; STDMETHOD_ (ULONG, GetUserPositionStatus) (THIS) PURE; STDMETHOD_ (BSTR, GetUserPositionStr) (THIS) PURE; STDMETHOD_ (ULONG, OpenPositionManager) (THIS_ BSTR) PURE; STDMETHOD_ (ULONG, WaitForPositionManagerEnd) (THIS) PURE; STDMETHOD_ (BSTR, GetPositionFile) (THIS) PURE; STDMETHOD (SetPositionFile) (THIS_ BSTR) PURE; STDMETHOD_ (ULONG, Laser) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, SetAccel) (THIS_ ULONG) PURE; STDMETHOD_ (ULONG, GetAccel) (THIS_ VARIANT) PURE; STDMETHOD_ (ULONG, GetAccelStatus) (THIS) PURE; STDMETHOD_ (ULONG, GetAccelNum) (THIS) PURE; }; typedef struct { Rob5xVtbl *lpVtbl; DWORD count; char buffer[80]; } MyRob5x; /* Deux fonctions pour traduire les chaines de type BSTR vers des types classiques */ void BSTRtoASC(BSTR str, char *strRet) { if(str != NULL) { ULONG length = WideCharToMultiByte(CP_ACP, 0, str, SysStringLen(str), NULL, 0, NULL, NULL); strRet = malloc(sizeof(char)*length); length = WideCharToMultiByte(CP_ACP, 0, str, SysStringLen(str), strRet, length, NULL, NULL); strRet[length] = '\0'; } } void ASCtoBSTR(char *str, BSTR *strRet) { if(str != NULL) { ULONG length = strlen(str); int ResultLength = MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED, str,length,NULL,0); *strRet = SysAllocStringLen(NULL, ResultLength); MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED, str,length,*strRet,ResultLength); } } int main(void) { LPVOID *pIFace = NULL; Rob5x *Robot = NULL; HRESULT resultat = 0; ULONG retVal; IClassFactory *classFactory = NULL; char *chaine = NULL; wchar_t chaineW[] = L"COM3"; BSTR chaineBSTR = NULL; chaineBSTR = SysAllocStringLen(chaineW, sizeof(chaineW)); /* On récupère l'objet, on lance une instance et on tente une communication avec le robot */ if(!CoInitialize(NULL)) { resultat = CoGetClassObject(&CLSID_Rob5x, CLSCTX_ALL, 0, &IID_IClassFactory, &classFactory); if(resultat) printf("Erreur pour obtenir l'objet: 0x%08.8X\n", resultat); else { resultat = classFactory->lpVtbl->CreateInstance(classFactory, 0, &IID_Rob5x, &Robot); if(resultat) { classFactory->lpVtbl->Release(classFactory); printf("Erreur de creation d'instance: 0x%08.8X\n", resultat); } else { classFactory->lpVtbl->Release(classFactory); ASCtoBSTR("COM3", &chaineBSTR); wprintf(L"String: %s\n", chaineBSTR); retVal = Robot->lpVtbl->OpenComm(Robot, chaineBSTR); //Robot->lpVtbl->OpenManualBox(Robot); printf("Valeur : 0x%08.8X", retVal); //wprintf(L"Numero de serie : %s\n", Robot->lpVtbl->GetSerialNumber(Robot)); Robot->lpVtbl->CloseComm(Robot); Robot->lpVtbl->Release(Robot); CoUninitialize(); return 0; } } } printf("resultat : %d\n", resultat); return 0; }
Il hérite des interfaces mentionnés dans le code, et voici le rendu de ses propriétés obtenus via l'outil oleview.exe :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 // Generated .IDL file (by the OLE/COM Object Viewer) // // typelib filename: Rob5x.exe [ uuid(3CF4288A-9CB4-44DE-8CB2-8EDC34EB5A7C), version(1.0), helpstring("RobX 1.0 Type Library"), custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 100663657), custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1360058814), custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, Created by MIDL version 6.00.0361 at Tue Feb 05 11:06:53 2013 ) ] library RobXLib { // TLib : // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046} importlib("stdole2.tlb"); // Forward declare all types defined in this typelib interface IRobX; [ uuid(5DD00CD6-E135-4799-A83F-62F06688700F), helpstring("CoRobX Class") ] coclass CoRobX { [default] interface IRobX; }; [ odl, uuid(92507B34-D92D-4F8C-967E-6C5166C0F1F6), helpstring("IRobX Interface"), dual, nonextensible, oleautomation ] interface IRobX : IDispatch { [id(0x00000001), helpstring("method CloseComm")] HRESULT CloseComm([out, retval] unsigned long* retVal); [id(0x00000002), helpstring("method Energize")] HRESULT Energize( [in] unsigned long activate, [out, retval] unsigned long* retVal); [id(0x00000003), helpstring("method GetErrorInfo")] HRESULT GetErrorInfo( [in] unsigned long errorCode, [out, retval] BSTR* retStr); [id(0x00000004), helpstring("method GetCurrentPosition")] HRESULT GetCurrentPosition( [in] VARIANT coordArray, [out, retval] unsigned long* retVal); [id(0x00000005), helpstring("method GetString")] HRESULT GetString( [in] VARIANT readBytes, [out, retval] unsigned long* retVal); [id(0x00000006), helpstring("method GotoHome")] HRESULT GotoHome( [in] unsigned long timeout, [out, retval] unsigned long* retVal); [id(0x00000007), helpstring("method GotoPoint")] HRESULT GotoPoint( [in] BSTR name, [in] unsigned long timeout, [out, retval] unsigned long* retVal); [id(0x00000008), helpstring("method GotoPosition")] HRESULT GotoPosition( [in] long X, [in] long Y, [in] long Z, [in] long W, [in] long P, [in] unsigned long timeout, [out, retval] unsigned long* retVal); [id(0x00000009), helpstring("method GotoUserPosition")] HRESULT GotoUserPosition( [in] unsigned long timeout, [out, retval] unsigned long* retVal); [id(0x0000000a), helpstring("method InitRobot")] HRESULT InitRobot([out, retval] unsigned long* retVal); [id(0x0000000b), helpstring("method MemPointPosition")] HRESULT MemPointPosition( [in] long X, [in] long Y, [in] long Z, [in] long W, [in] long P, [in] BSTR name, [out, retval] unsigned long* retVal); [id(0x0000000c), helpstring("method Move")] HRESULT Move( [in] unsigned long X, [in] unsigned long Y, [in] unsigned long Z, [in] unsigned long timeout, [out, retval] unsigned long* retVal); [id(0x0000000d), helpstring("method OpenComm")] HRESULT OpenComm( [in] BSTR portName, [out, retval] unsigned long* retVal); [id(0x0000000e), helpstring("method RestoreUserDefaultPosition")] HRESULT RestoreUserDefaultPosition([out, retval] unsigned long* retVal); [id(0x0000000f), helpstring("method SendString")] HRESULT SendString( [in] BSTR bytesToSend, [out, retval] unsigned long* retVal); [id(0x00000010), helpstring("method SetSpeed")] HRESULT SetSpeed( [in] unsigned long speed, [out, retval] unsigned long* retVal); [id(0x00000011), helpstring("method SetUserPosition")] HRESULT SetUserPosition( [in] long X, [in] long Y, [in] long Z, [in] long W, [in] long P, [out, retval] unsigned long* retVal); [id(0x00000012), helpstring("method Wait")] HRESULT Wait( [in] unsigned long millisecs, [out, retval] unsigned long* retVal); [id(0x00000013), helpstring("method SetLimits")] HRESULT SetLimits( [in] long Xmin, [in] long Xmax, [in] long Ymin, [in] long Ymax, [in] long Zmin, [out, retval] unsigned long* retVal); [id(0x00000014), helpstring("method RestoreDefaultLimits")] HRESULT RestoreDefaultLimits([out, retval] unsigned long* retVal); [id(0x00000015), helpstring("method GetLimits")] HRESULT GetLimits( [in] VARIANT Limits, [out, retval] unsigned long* retVal); [id(0x00000016), helpstring("method SetToolParam")] HRESULT SetToolParam( [in] long ToolLength, [out, retval] unsigned long* retVal); [id(0x00000017), helpstring("method GetToolParam")] HRESULT GetToolParam([out, retval] long* ToolLength); [id(0x00000018), helpstring("method Align")] HRESULT Align( [in] unsigned long activate, [out, retval] unsigned long* retVal); [id(0x00000019), helpstring("method GetVacuum")] HRESULT GetVacuum( [in] VARIANT vacuum, [out, retval] unsigned long* retVal); [id(0x0000001a), helpstring("method Pump")] HRESULT Pump( [in] unsigned long activate, [out, retval] unsigned long* retVal); [id(0x0000001b), helpstring("method Valve")] HRESULT Valve( [in] unsigned long open, [out, retval] unsigned long* retVal); [id(0x0000001c), helpstring("method OpenManualBox")] HRESULT OpenManualBox([out, retval] unsigned long* retVal); [id(0x0000001d), helpstring("method GetSpeed")] HRESULT GetSpeed( [in] VARIANT speed, [out, retval] unsigned long* retVal); [id(0x0000001e), helpstring("method WaitForManualBoxEnd")] HRESULT WaitForManualBoxEnd([out, retval] unsigned long* retVal); [id(0x0000001f), helpstring("method GetSerialNumber")] HRESULT GetSerialNumber([out, retval] BSTR* serialNumber); [id(0x00000020), helpstring("method GetUserPosition")] HRESULT GetUserPosition( [in] VARIANT userPosition, [out, retval] unsigned long* retVal); [id(0x00000021), helpstring("method Calibrate")] HRESULT Calibrate( [in] long ask, [out, retval] unsigned long* retVal); [id(0x00000022), helpstring("method GetSpeedStatus")] HRESULT GetSpeedStatus([out, retval] unsigned long* retVal); [id(0x00000023), helpstring("method GetSpeedNum")] HRESULT GetSpeedNum([out, retval] unsigned long* speed); [id(0x00000024), helpstring("method GetCurrentPositionStatus")] HRESULT GetCurrentPositionStatus([out, retval] unsigned long* retVal); [id(0x00000025), helpstring("method GetCurrentPositionStr")] HRESULT GetCurrentPositionStr([out, retval] BSTR* coordStr); [id(0x00000026), helpstring("method GetLimitsStatus")] HRESULT GetLimitsStatus([out, retval] unsigned long* retVal); [id(0x00000027), helpstring("method GetLimitsStr")] HRESULT GetLimitsStr([out, retval] BSTR* limitsStr); [id(0x00000028), helpstring("method GetVacuumStatus")] HRESULT GetVacuumStatus([out, retval] unsigned long* retVal); [id(0x00000029), helpstring("method GetVacuumNum")] HRESULT GetVacuumNum([out, retval] unsigned long* vacuum); [id(0x0000002a), helpstring("method GetUserPositionStatus")] HRESULT GetUserPositionStatus([out, retval] unsigned long* retVal); [id(0x0000002b), helpstring("method GetUserPositionStr")] HRESULT GetUserPositionStr([out, retval] BSTR* coordStr); [id(0x0000002c), helpstring("method OpenPositionManager")] HRESULT OpenPositionManager( [in] BSTR positions, [out, retval] unsigned long* retVal); [id(0x0000002d), helpstring("method WaitForPositionManagerEnd")] HRESULT WaitForPositionManagerEnd([out, retval] unsigned long* retVal); [id(0x0000002e), propget, helpstring("property PositionFile")] HRESULT PositionFile([out, retval] BSTR* filePath); [id(0x0000002e), propput, helpstring("property PositionFile")] HRESULT PositionFile([in] BSTR filePath); [id(0x0000002f), helpstring("method Laser")] HRESULT Laser( [in] unsigned long activate, [out, retval] unsigned long* retVal); [id(0x00000030), helpstring("method SetAccel")] HRESULT SetAccel( [in] unsigned long accel, [out, retval] unsigned long* retVal); [id(0x00000031), helpstring("method GetAccel")] HRESULT GetAccel( [in] VARIANT accel, [out, retval] unsigned long* retVal); [id(0x00000032), helpstring("method GetAccelStatus")] HRESULT GetAccelStatus([out, retval] unsigned long* retVal); [id(0x00000033), helpstring("method GetAccelNum")] HRESULT GetAccelNum([out, retval] unsigned long* speed); }; };
Je vous remercie d'avance si vous avez une idée sur le sujet.
Si vous avez des liens sur le sujet en complément, cela m'intéresse également.![]()
Partager