Bonjour, je cherche a créer un composant utilisant la norme COM, j'ai lu et suivi le document du MSDN "The COM Programmer's Cookbook"
lien : http://msdn.microsoft.com/library/en...sdn_com_co.asp
J'ai créé une interface de test, j'ai compilé avec MIDL :
LA compilation m'a produit 4 fichiers : dlldata.c, ITest_i.c, ITest_p.c, ITest.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 import "oaidl.idl"; import "ocidl.idl"; //typedef [string] char line[81]; [ object, uuid(A46C12C0-4E88-11ce-A6F1-00AA0037DEFB) ] interface ITest : IUnknown { HRESULT showMessage ([in, string] char * msg); };
------------------------
J'ai ensuite tenté de créer un contrôle qui implémenterait cette interface :
je veux juste faire un composant qui aurait une méthode qui affiche un texte via une msgbox.
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 #include <objbase.h> #include "ITest.h" int vcObjects = 0; // Création du composant : struct CMyComponent : ITest { // IUnknown methods HRESULT __stdcall QueryInterface (REFIID riid, void **ppv); ULONG __stdcall AddRef (void); ULONG __stdcall Release (void); // ITest methods HRESULT __stdcall showMessage( unsigned char *msg); // constructeur CMyComponent(); // membres int m_cRef; }; /*********************************************************** * QueryInterface ***********************************************************/ HRESULT CMyComponent::QueryInterface (REFIID riid, void **ppv) { if (riid == IID_IUnknown || riid == IID_ITest) *ppv = (ITest *) this; else { *ppv = 0; return E_NOINTERFACE; } ((IUnknown *)*ppv)->AddRef (); return NOERROR; } /*********************************************************** * AddRef ***********************************************************/ ULONG CMyComponent::AddRef (void) { return ++ m_cRef; } /*********************************************************** * Release ***********************************************************/ ULONG CMyComponent::Release (void) { if (--m_cRef == 0) { --vcObjects; delete this; return 0; } return m_cRef; } /*********************************************************** * showMessage ***********************************************************/ HRESULT CMyComponent::showMessage(unsigned char *msg) { MessageBox(NULL, (LPCSTR)msg, "Message COM", MB_OK); return NOERROR; } /*********************************************************** * Constructeur ***********************************************************/ inline CMyComponent::CMyComponent (void) { m_cRef = 1; ++vcObjects; } extern "C" HRESULT CreateAvolute (IUnknown *punkOuter, REFIID riid, void **ppv) { CMyComponent *pout; *ppv = 0; if (punkOuter) return CLASS_E_NOAGGREGATION; if (!(pout = new CMyComponent)) return E_OUTOFMEMORY; HRESULT hr = pout->QueryInterface (riid, ppv); pout->Release (); return hr; }
lorsque je compile j'obtient un : error LNK2001: unresolved external symbol _IID_ITest
IID_ITest est pourtant bien définie dans ITest.h (généré par MIDL) :
je ne sais pas pourquoi il le défini en EXTERN mais visiblement ça pose pb.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2EXTERN_C const IID IID_ITest;
Pour info : je suis sous XP avec Visual studio 8 et j'ai créer unn projet de type DLL extended stored procedure en enlevant les fichiers relatif aux base de données, ne sachant pas quel projet chosir pour créer un composant COM.
J'ai l'impression que des paramètres manquent dans la config de mon projet et que le linker ne si retrouve pas.
Pour tester j'ai remplacé "EXTERN_C const IID IID_ITest" par "const IID IID_ITest" dans Itest.h et j'ai continué à programmer. Au moment, d'utiliser une macro microsoft faisant elle aussi appelle a des extern C ca a planté au linkage :
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 // {A46C12C0-4E88-11ce-A6F1-00AA0037DEFB} DEFINE_GUID(CLSID_Avolute, 0xa46c12c0, 0x4e88, 0x11ce, 0xa6, 0xf1, 0x0, 0xaa, 0x0, 0x37, 0xde, 0xfb); void createComposantTest(){ // création d'un composant COM ITest *pTest; HRESULT hr; int result; // initialisation de COM hr = CoInitialize(NULL); hr = CoCreateInstance(CLSID_
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 MyComponent, NULL, CLSCTX_SERVER, IID_ITest, (LPVOID *)&pTest); // .... pTest->showMessage((unsigned char*)"message test"); }
Je ne comprend pas les erreurs de linkage. Déjà que je comprend pas trop COM, je galère un max là.
julien
Partager