Développement d'un composant COM
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 :
Code:
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);
}; |
LA compilation m'a produit 4 fichiers : dlldata.c, ITest_i.c, ITest_p.c, ITest.h
------------------------
J'ai ensuite tenté de créer un contrôle qui implémenterait cette interface :
Code:
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;
} |
je veux juste faire un composant qui aurait une méthode qui affiche un texte via une msgbox.
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) :
Code:
1 2
|
EXTERN_C const IID IID_ITest; |
je ne sais pas pourquoi il le défini en EXTERN mais visiblement ça pose pb.
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:
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:
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