2017-05-29 2 views
0

J'ai deux bibliothèques: IDA et XIDA.
XIDA gère la boucle d'événements, et il y a pour chaque application/processus, une boucle d'événement unique. Et ces bibliothèques sont "connectées" via une fonction de rappel.XLib XSendEvent sur d'autres applications/processus

Cela fonctionne avec des événements à l'intérieur d'une seule application/processus ...

Maintenant, je remarquai que je pouvais envoyer un événement d'une application à une autre. Ce dont il a besoin, c'est une poignée de fenêtre d'une autre application. J'ai donc codé un message DBus, avec ce que je peux en recevoir un ...

Cela fonctionne aussi, mais il semble que le récepteur de XSendEvent() ne peut utiliser que des fonctions et ses paramètres, sans variables membres!

Dans le HPP:

 Window mSection; 
     Window Section(){ 
      return 0; // This is working 
     } 
     Window Section_A(){ 
      return this->mSection; // This raises a memory access error 
     } 
     int CheckEvents(IDA_A *vIDA_A, XEvent vEvent); 
     static int Section_EventCallback(void* this_ptr, XEvent vEvent){ 
     IDA_A* nIDA_A = NULL; 
     int nRet = 1; 
      try{ 
       nIDA_A = static_cast < IDA_A* > (this_ptr); 
      } catch (...) { return 0; } 

      cout << "TEST " << nIDA_A->Section() << endl; // This is working, also with any other function 

      cout << "TEST " << nIDA_A->mSection << endl; // This raises a memory access error, also with any other member variable 

      cout << "TEST " << nIDA_A->Section_A() << endl; // This also raises a memory access error 

      nRet = nIDA_A->CheckEvents(nIDA_A, vEvent); 
      nIDA_A = NULL; 
      return nRet; 
     } 

Dans le cpp:

 int IDA_A::CheckEvents(IDA_A *vIDA_A, XEvent vEvent) { 
     Window nWindow = vEvent.xany.window; 
     cout << "TEST " << " -- " << nWindow << endl; // This is working 
     cout << "TEST " << " -- " << this->mSection << endl; // This raises a memory access error 
     return 1; 
     } 

Que faut-il besoin d'utiliser aussi des variables membres?

Cordialement
Earlybite

------------------------ EDIT: ------------ ----------------

Ceci est la partie de XIDA où XSendEvents() arrive (après avoir appelé à l'intérieur de la boucle d'événements):

int XIDA_A::Send_To_Callback(XEvent vEvent){ 
     for(int i = 0; i < (int) this->mVecEvCallback.size(); i++){ 
      if(*this->mVecEvCallback[i].pWindow == vEvent.xany.window){ 
       if(vEvent.type == ClientMessage) { 
        cout << "THIS XIDA CLIENT " << this->mIdent << endl; 
       } 
       s_EventCallback nEvCallback; 
       nEvCallback = this->mVecEvCallback[i]; 
       nEvCallback.Callback (nEvCallback.this_Ptr, vEvent); 
       return 1; 
      } 
     } 
     return 0; 
    } 

Et ce point, ça marche, aussi les variables membres. Mais jamais plus à l'IDA, où le Callback va.
Mais c'est le même processus!
Et par exemple. avec DBus cela fonctionne ...
Je voudrais vraiment connaître la raison!

+0

compilez avec tous les avertissements et les informations de débogage ('g ++ -Wall -Wextra -g' avec [GCC] (http://gcc.gnu.org/) ...) et ** utiliser le débogueur' gdb' * *. Vous ne montrez pas assez de code (et si vous le faisiez, votre question serait toujours hors sujet).BTW, vous ne pouvez pas envoyer d'adresses ou de pointeurs avec 'XSendEvent' (car les processus émetteur et récepteur peuvent être sur des machines différentes, et ont certainement des [espaces d'adressage virtuel] différents (https://en.wikipedia.org/wiki/Virtual_address_space) ....) –

+0

Je n'envoie aucun pointeur avec XSendEvent(). XSendEvents() envoie avec un handle de fenêtre et l [1] = 1 et dans XIDA et sa boucle d'événement il sera reçu. Cela devrait donc être un autre processus que l'expéditeur a. Dans XIDA est un vecteur dans lequel par ex. le rappel est enregistré. Ainsi, le récepteur AFAIK devrait utiliser aussi les variables membres, non seulement les fonctions et leurs paramètres ... – Earlybite

+0

Ceci est la partie dans XIDA où XSendEvent() reçoit à partir de laquelle le Callback est envoyé: int XIDA_A :: Send_To_Callback (XEvent vEvent) { \t for (int i = 0; i <(int) this-> mVecEvCallback.size(); i ++) { \t \t if (* this-> mVecEvCallback [i] == .pWindow vEvent.xany.window) { \t \t \t if (vEvent.type == ClientMessage) { \t \t \t \t cout << "ce client XIDA" << this-> MIDENT << endl; \t \t \t} \t \t s_EventCallback nEvCallback; \t \t \t nEvCallback = this-> mVecEvCallback [i]; \t \t \t nEvCallback.Callback (nEvCallback.this_Ptr, vEvénement); \t \t \t retour 1; \t \t} \t} \t return 0; } Travailler, mais pas dans IDA, qui est appelé à partir du rappel – Earlybite

Répondre

0

RÉSOLU.
J'ai trouvé l'erreur ...

Ce

est une partie de init.

Et j'avais oublié de mettre

nMsg.Para_ThisPtr = (void*) this; 

Mais ce que je ne comprends toujours pas ...

static int Section_EventCallback(void* this_ptr, XEvent vEvent){ 
IDA_A* nIDA_A = NULL; 
int nRet = 1; 
    try{ 
     nIDA_A = static_cast < IDA_A* > (this_ptr); 
    } catch (...) { return 0; } 
    nRet = nIDA_A->CheckEvents(nIDA_A, vEvent); 
    nIDA_A = NULL; 
    return nRet; 
} 

vient ici/est venu le pointeur avec NULL.
Pourquoi nIDA_A n'était-il pas NULL ou pourquoi n'y a-t-il pas eu d'erreur, car static_cast ne peut pas lancer NULL?
Et pourquoi les fonctions fonctionnaient-elles, mais pas les variables membres?

Vous savez ce que je veux dire?