2017-03-14 6 views
0

Nous construisons une bibliothèque qui contient quelques QObjects et QWidgets. L'idée est de fournir des objets COM en utilisant ActiveX (QAxContainer) afin qu'ils puissent être intégrés et utilisés conjointement avec d'autres langages (dans ce cas, C# géré).Appel de QCoreApplication :: arguments() crashes à l'aide d'un serveur ActiveX

Certains des objets que nous utilisons s'intègrent à Qt Quick et pour ce faire, nous utilisons QQuickWidget. Lors de la construction de QQuickWidget il invoquera QCoreApplication :: arguments() ce qui conduit à une violation d'accès lecture: Exception thrown at 0x00007ffc43f12fc0 (ucrtbased.dll) in WinClient.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff

Exporter la classe suivante à un widget de ActiveX conduira à l'accident:

#include <QWidget> 
#include <ActiveQt/QAxBindable> 

class TestAxWidget: public QWidget, public QAxBindable 
{ 
    Q_OBJECT 

    Q_CLASSINFO("ClassID",  "{377794ac-85f2-4e2c-be17-f2852d85fa61}") 
    Q_CLASSINFO("InterfaceID", "{8b3a6ef3-9d17-47f7-99a8-cd96d0d922dd}") 
    Q_CLASSINFO("EventsID",  "{12e9000e-017e-454e-a641-73c9p8349d77}") 
    Q_CLASSINFO("CoClassAlias", "TestAxWidget") 
    Q_CLASSINFO("RegisterObject", "yes") 

    public: 
    explicit TestAxWidget(QWidget * parent = Q_NULLPTR) 
     : QWidget(parent) 
    { 
     QCoreApplication::arguments(); 
    } 
     Q_DISABLE_COPY(TestAxWidget) 
}; 

Et pile trace:

ucrtbased.dll!strlen() + 0x10 bytes  
Qt5Cored.dll!QString::fromLocal8Bit(const char * str, int size) Line 539 + 0x19 bytes C++ 
Qt5Cored.dll!QCoreApplication::arguments() Line 2313 + 0x1e bytes C++ 

Des suggestions sur comment résoudre ce problème?


Mise à jour

Après un nouvel débogage en utilisant les sources Qt que j'ai trouvé que le argc donné au QCoreApplication() est initialisé à 0 (zéro).

Lorsque QCoreApplication :: arguments() est invoqué, la valeur de argc est passée à une valeur élevée aléatoire! = 0, ce qui entraîne évidemment une exception.

J'ai utilisé un Data Breakpoint dans VS2015 pour identifier quand la valeur de argc est changée et il semble être changé périodiquement par clr.dll. Comment puis-je empêcher cela? est-ce que je fais quelque chose de fondamentalement faux?

Actuellement en utilisant Qt 5.6.2 sur Windows 10 x64 VS2015

Répondre

0

Apparemment, il y a un bug lorsque le QApplication est instansiated dans QAxServerBase.cpp, par fonction CreateInstanceHelper:

... 
if (!qApp) { 
    qax_ownQApp = true; 
    int argc = 0; 
    new QApplication(argc, 0); 
} 
... 

Les accidents d'application depuis le passé dans l'argument argc est créé sur la pile et ne survivra pas QApplication -exemple.

Il y a un bug-fix pour cette version 5.9.0: https://bugreports.qt.io/browse/QTBUG-59047

0

Je pense que la seule façon de résoudre ce sans modifier l'application principale (écrite est C# je pense) est de créer une instance QApplication dans votre bibliothèque et exécutez QApplication :: exec pour les messages GUI de dispatch depuis/vers les instances QWidgets.

+0

semble un peu excessif non? J'ai été chanceux parfois avec le binaire compilé afin que strlen ne lève pas une exception et il fonctionne alors sans n'importe quel hoquet. –

+0

Oui, il s'agit d'une limitation de conception, tous les widgets doivent être gérés dans le seul thread GUI contrôlé par QApplication – em2er

+0

Nous utilisons une pompe de message dans l'application C# pour la livraison des événements. Notez par exemple que créer un QWidget standard (et non un QQuickWidget) n'est pas un problème. –