juin
2007
Pour continuer avec COM Interop, je vais vous montrer comment passer des paramètres à une méthode.
soit la classe CLI suivante :
public ref class MaClasse
{
public:
MaClasse()
{
}
String ^ Print(String ^c, int val)
{
Console::WriteLine("entier passé : {0}", val);
return c + " " + DateTime::Now.ToString();
}
};
}
La méthode Print attend en paramètre une String ^ et un entier. La méthode affiche l’entier et renvoie la chaine passée en paramètre concaténée à la date du jour sous la forme d’une String ^.
Enregistrez l’assembly pour com interop comme expliqué dans le billet précédent. Je conseille personnelement de rajouter dans les post build events, la ligne de commande qui enregistre la dll, soit :
« C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe » « $(OutDir)\assembly.dll » /tlb: »$(OutDir)\assembly.tlb » /codebase
Voici le code C++ natif qui va permettre d’appeler l’objet COM Wrapper :
#include <iostream>
void BSTRtoASC (BSTR str, char * &strRet)
{
if ( str != NULL )
{
unsigned long length = WideCharToMultiByte (CP_ACP, 0, str, SysStringLen(str),
NULL, 0, NULL, NULL);
strRet = new char[length];
length = WideCharToMultiByte (CP_ACP, 0, str, SysStringLen(str),
reinterpret_cast <char *>(strRet), length, NULL, NULL);
strRet[length] = '\0';
}
}
int _tmain(int argc, _TCHAR* argv[])
{
DISPID dispid;
IDispatch *pDisp;
OLECHAR *methodName = L"Print";
CLSID clsID;
VARIANT vntArgs[2], vntResult;
DISPPARAMS param;
param.cArgs = 2;
param.rgvarg = vntArgs;
param.cNamedArgs = 0;
param.rgdispidNamedArgs = NULL;
vntArgs[0].vt = VT_INT;
vntArgs[0].intVal = 10;
vntArgs[1].vt = VT_BSTR;
vntArgs[1].bstrVal = SysAllocString(L"Nous sommes le");
vntResult.vt = VT_BSTR;
CoInitialize(NULL);
if (SUCCEEDED(::CLSIDFromProgID(L"assembly.MaClasse", &clsID)))
if (SUCCEEDED(CoCreateInstance(clsID, NULL, CLSCTX_ALL, IID_IDispatch, (void**)&pDisp)))
if (SUCCEEDED(pDisp->GetIDsOfNames(IID_NULL, &methodName,1, GetUserDefaultLCID(), &dispid)))
if (SUCCEEDED(pDisp->Invoke(dispid, IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, &vntResult, NULL, NULL)))
{
char * retour;
BSTRtoASC(vntResult.bstrVal, retour);
std::cout << retour << std::endl;
pDisp->Release();
}
CoUninitialize();
return 0;
}
La partie importante est dans la construction des paramètres et dans l’utilisation du paramètre de retour.
On construit un tableau de VARIANT à 2 dimensions VARIANT vntArgs[2] qui va recevoir les deux paramètres de la fonction.
Attention, les paramètres doivent être passés dans le sens inverse !
Pour mapper une String ^, on va utiliser un BSTR. C’est ce qu’on indique grace à cette ligne : vntArgs[1].vt = VT_BSTR;
La valeur passée sera : vntArgs[1].bstrVal = SysAllocString(L »Nous sommes le »);
Notez qu’on utilise le couple {VT_BSTR, bstrVal} pour faire passer une chaine.
Pour l’entier, c’est le même principe, on va utiliser le couple {VT_INT, intVal}.
Vous pouvez retrouver plus d’infos sur les VARIANT à cette adresse.
Pour le retour de la méthode, on utilise un autre variant vntResult, qu’on indique comme étant un BSTR.
Une fois l’appel à la méthode effectuée, il ne reste plus qu’à traiter le retour. On utilise la méthode de conversion de la faq VC pour avoir un char * et l’afficher.
Et voilà.
Commentaires récents
- [Tests] Arrange Act Assert, une traduction ? dans
- [UnitTest][C#] Tester une méthode privée dans
- Récupérer une valeur d’un contrôle depuis une autre Form / inclusions croisées et déclaration anticipée dans
- Tutoriel : Utiliser la ListBox et l’Isolated Storage dans vos applications Windows Phone 7 avec Silverlight dans
- Tutoriel : Utiliser la ListBox et l’Isolated Storage dans vos applications Windows Phone 7 avec Silverlight dans
Archives
- janvier 2013
- avril 2012
- janvier 2012
- juin 2011
- janvier 2011
- décembre 2010
- novembre 2010
- septembre 2010
- juin 2010
- mars 2010
- février 2010
- janvier 2010
- décembre 2009
- novembre 2009
- octobre 2009
- septembre 2009
- août 2009
- juillet 2009
- mai 2009
- avril 2009
- mars 2009
- janvier 2009
- décembre 2008
- novembre 2008
- octobre 2008
- septembre 2008
- août 2008
- juillet 2008
- juin 2008
- mai 2008
- avril 2008
- mars 2008
- février 2008
- janvier 2008
- décembre 2007
- novembre 2007
- octobre 2007
- septembre 2007
- août 2007
- juillet 2007
- juin 2007
- mai 2007