Salut tlm,
Est ce que quelqu'un pourrait m'indiquer comment faire pour passer une liste de char entre un serveur COM et son client?
Merci d'avance.
Salut tlm,
Est ce que quelqu'un pourrait m'indiquer comment faire pour passer une liste de char entre un serveur COM et son client?
Merci d'avance.
ca veut dire quoi ca une liste de char ?
un truc de ce genre
serait l'idéal.list<char*, allocator<char*> >
Euh... On n'est pas supposé utiliser des BSTR en COM ?
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Dans ce cas, tu saurais pas comment faire pour faire passer une liste de BSTR ou du moins un tableau?
Ben, ça dépend de ce que tu veux faire...
Personnellement, je n'ai touché à COM qu'en InprocServer, donc où pour passer des données, il suffit de passer le pointeur...
Si c'est ce que tu veux faire, ben, le mieux est d'allouer un tableau de BSTR (le type BSTR est un simple pointeur), le passer en paramètre à une fonction et le désallouer soi-même après usage...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Voici la méthode que j'ai implémenté au niveau de mon serveur COM :
Et voici comment je l'ai appelé au niveau de mon client:STDMETHODIMP Test::GetServers(/*[in]*/ BSTR NodeName,/*[out]*/ BSTR** servertable) {
//Some code
BSTR* ptable = new BSTR[255];
//.....
*servertable = ptable;
return S_OK;
}
Mais ça ne marche pas : servertable_ ne contient qu'un seul élément alors qu'elle devrait en avoir 70.BSTR* servertable_ = new BSTR[255];
_bstr_t nodename("localhost");
pIFTest->GetServers(nodename,&servertable_);
J'ai essayé de crée ma propre structure de liste dans le fichier idl :
Mais le client plante dès la déclaration d'un objet ELEMENT.typedef struct tagELEMENT {
BSTR lValue;
[unique] struct tagELEMENT* pNext;
} ELEMENT;
Tu es sûr que le problème n'est pas au REMPLISSAGE du tableau ou à la détection du nombre ?
PS: Tu alloues le tableau dans le client ou dans le serveur, mais tu ne dois pas le faire dans les deux: L'un des deux tableaux est perdu...
PPS: n'oublions pas que ce qui est alloué par un module doit généralement être désalloué par le même module. Il te faudra donc soit allouer et désallouer le tableau dans le client COM, soit exporter une fonction de désallocation dans le serveur COM.
PPPS: Pour l'IDL, je ne peux pas t'aider, je ne connais pas. Moi, j'utilise de simples headers C/C++ avec la macro DECLARE_INTERFACE.
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
J'alloue le tableau dans le client.
Je vais vérifier le remplissage, je crois ne pas l'avoir fait.
Merci.
ALORS COMMENT SAIS-TU QUE TU AS UN SEUL ELEMENT AU LIEU DE 70 ?Envoyé par mambo
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
En fait, j'ai une liste qui contient 70 élément (de type string) que je dois mettre dans le tableau servertable.
Mais au niveau du client, je ne retrouve que le premier élément.
Ben forcément, si t'as pas encore fait le remplissage...![]()
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Mais si justement je l'ai rempli![]()
Dans ce cas montre-moi comment tu remplis et comment tu lis...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Voilà la méthode implémentée au niveau du serveur COM :
Je viens de revérifier cette méthode, le iq est là :typedef list<char*, allocator<char*> > charlist;
STDMETHODIMP Test::GetServers(/*[in]*/ BSTR NodeName,/*[out]*/ BSTR** servertable) {
charlist *ServerList = new charlist;
HRESULT hrt = GetLocalServerList(1,strCATID, 1,ServerList);
int i = 0;
list<char*, allocator<char*> > ::iterator SLit;
if (ServerList->size()> 0)
{
SLit = ServerList->begin();
string servername;
BSTR ptable[255];
int i = 0;
while (SLit!= ServerList->end())
{
servername = (*SLit);
CComBSTR tempo(servername.begin());
ptable[i] = tempo.Detach();
i++;
SLit++;
LocalFree(tempo);
}
*servertable = ptable;
}
}
return S_OK;
}
*servertable = ptable;
Donc,
- Tu n'alloues plus le tableau dans le serveur. C'est bien.
- Tu retournes l'adresse d'une variable locale. C'est mal.
- Je ne connais pas trop CComBSTR, mais je ne vois pas trop à quoi sert le LocalFree() dessus?
Bref, pour le 2, tu dois recopier le tableau au lieu de passer son adresse. À supposer que *servertable fasse toujours 255 BSTRs, tu peux passer un simple BSTR* et utiliser une boucle FOR pour remplir le tableau...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Je viens de corriger la méthode au niveau du serveur, le remplissage se fait correctement. Voilà la dernière modification de la méthode au niveau du serveur COM :
Mais j'ai toujours pas le bon résultat au niveau du client :typedef list<char*, allocator<char*> > charlist;
STDMETHODIMP Test::GetServers(/*[in]*/ BSTR NodeName,/*[out]*/ BSTR** servertable) {
charlist *ServerList = new charlist;
HRESULT hrt = GetLocalServerList(1,strCATID, 1,ServerList);
int i = 0;
list<char*, allocator<char*> > ::iterator SLit;
if (ServerList->size()> 0)
{
SLit = ServerList->begin();
string servername;
BSTR ptable[255];
int i = 0;
while (SLit!= ServerList->end())
{
servername = (*SLit);
CComBSTR tempo(servername.begin());
ptable[i] = tempo.Detach();
i++;
SLit++;
LocalFree(tempo);
}
for (int j=0; j < 255; j++) {
servertable[j] = &ptable[j];
//Some code....
}
}
return S_OK;
}
Qu'est ce qui est faux ici ?BSTR* servertable_ = new BSTR[255];
BSTR** servertable = &servertable_;
pIFTest->GetServers(nodename,servertable);
for (int i=0; i < 255; i++) {
char TABLE[255];
BSTR test = *servertable[i];
sprintf(TABLE, "%ws", test);
//Some code...
}
Pour localfree, je sais pas vraiment qu'est ce que c'est. C'est juste un truc que j'ai essayé et que j'ai oublié là.
Salut,
La bande passante est faible dans la passation des types de données entre un serveur COM et son client. C'est l'un défaut de COM.
Mais du moins tu peux passer n'importe quel types de données en faisant un petit cast dans un VARIANT.
C'est une de mes classes utilitaire de Mcn.dll
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 #pragma once namespace MCN { template<typename T> class CCastingVariant { public: static T* CastFromVariant(VARIANT var) { if(var.vt != VT_BYREF || var.byref == NULL) return NULL; return (T*) var.byref; } static VARIANT CastToVariant(T* pT) { if(pT == NULL) return CComVariant(); VARIANT var; var.byref = (void*) pT; var.vt = VT_BYREF; return var; } }; } // namespace MCN
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 // Dans un code client MonType monObjet; MonserveurCOM.Function(MCN::CCastingVariant<MonType>::CastToVariant(&monObjet));
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 // Dans le code serveur du composant COM HRESULT MonServeur::Function(VARIANT var) { MonType* pmonObjet = MCN::CCastingVariant<MonType>::CastFromVariant(var); //...![]()
Gabrielly : Je crois bien qu'on est en Inproc pour l'instant : Si tu parles de "Bande passante", c'est pour le marshalling, non?
mambo : Le code du client ne suffit pas. Tu peux ajouter la version définitive du serveur ? (en éditant ton post par exemple)
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Mon serveur est un serveur COM local exécutable.
J'ai utilisé cet exemple http://www.codeproject.com/com/LocalCOMServerClient.asp pour le réaliser.
Partager