外部DLL中缺少Qt信号

时间:2014-01-22 22:11:52

标签: c++ windows qt c++11 mingw

我在我的应用程序中使用的库,iris xmpp库中有信号。在Mac OS X和Linux上一切正常,但是Windows会产生大量未找到警告的信号。

warning: QObject::connect: signal not found in XMPP::AdvancedConnector
warning: QObject::connect: signal not found in XMPP::AdvancedConnector
warning: QObject::connect: signal not found in XMPP::AdvancedConnector
warning: QObject::connect: signal not found in XMPP::AdvancedConnector
warning: QObject::connect: signal not found in XMPP::QCATLSHandler
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::ClientStream
warning: QObject::connect: signal not found in XMPP::Client
warning: QObject::connect: signal not found in XMPP::Client
warning: QObject::connect: signal not found in XMPP::Client
warning: QObject::connect: signal not found in XMPP::Client

我尝试使用的一个信号示例是

signals:
    void srvLookup(const QString &server);

我的连接电话

conn = std::make_shared<XMPP::AdvancedConnector>();
QObject::connect(conn.get(), &XMPP::AdvancedConnector::srvLookup, this, &XmppConnection::connServerLookupHandler);
QObject::connect(conn.get(), &XMPP::AdvancedConnector::srvResult, this, &XmppConnection::connServerResultHandler);
QObject::connect(conn.get(), &XMPP::AdvancedConnector::httpSyncStarted, this, &XmppConnection::connHttpSyncStartedHandler);
QObject::connect(conn.get(), &XMPP::AdvancedConnector::httpSyncFinished, this, &XmppConnection::connHttpSyncFinishedHandler);

if(QCA::isSupported("tls")) {
    tls = make_unique<QCA::TLS>();
    tlsHandler = make_unique<XMPP::QCATLSHandler>(tls.get());
    // dont check the certificate because we self sign
    tlsHandler->setXMPPCertCheck(false);
    QObject::connect(tlsHandler.get(), &XMPP::QCATLSHandler::tlsHandshaken, this, &XmppConnection::tlsHandshakenHandler);
} else {
    tls = 0;
    tlsHandler = 0;
}

stream = std::make_shared<XMPP::ClientStream>(conn.get(), tlsHandler.get());
QObject::connect(stream.get(), &XMPP::ClientStream::connected, this, &XmppConnection::streamConnectedHandler);
QObject::connect(stream.get(), &XMPP::ClientStream::securityLayerActivated, this, &XmppConnection::streamSecurityLayerActivatedHanlder);
QObject::connect(stream.get(), &XMPP::ClientStream::needAuthParams, this, &XmppConnection::streamNeedAuthParamsHandler);
QObject::connect(stream.get(), &XMPP::ClientStream::authenticated, this, &XmppConnection::streamAuthenticatedHandler);
QObject::connect(stream.get(), &XMPP::ClientStream::connectionClosed, this, &XmppConnection::streamConnectionClosedHandler);
QObject::connect(stream.get(), &XMPP::ClientStream::delayedCloseFinished, this, &XmppConnection::streamDelayedCloseFinished);
QObject::connect(stream.get(), &XMPP::ClientStream::readyRead, this, &XmppConnection::streamReadyRead);
QObject::connect(stream.get(), &XMPP::ClientStream::stanzaWritten, this, &XmppConnection::streamStanzaWritten);
QObject::connect(stream.get(), &XMPP::ClientStream::warning, this, &XmppConnection::streamWarningHandler);
QObject::connect(stream.get(), &XMPP::ClientStream::error, this, &XmppConnection::streamErrorHandler);

xmpp = std::make_shared<XMPP::Client>();
QObject::connect(xmpp.get(), &XMPP::Client::rosterRequestFinished, this, &XmppConnection::onRosterRequestFinished);
QObject::connect(xmpp.get(), &XMPP::Client::rosterItemAdded, this, &XmppConnection::onRosterItemAdded);
QObject::connect(xmpp.get(), &XMPP::Client::rosterItemUpdated, this, &XmppConnection::onRosterItemUpdated);
QObject::connect(xmpp.get(), &XMPP::Client::rosterItemRemoved, this, &XmppConnection::onRosterItemRemoved);

这是我的一个实际插槽

void XmppConnection::connServerLookupHandler(const QString &server)
{
    qDebug() << "Looking up Server: " << server;
    return;
}

我无法弄清楚为什么mac和linux的工作和windows没有。我已经考虑过编译器选项,但是我使用cmake所以除非我的linux gcc和我的mingw gcc之间有一些巨大的区别我不明白为什么那会很重要。我正在使用C ++ 11功能,这可以通过我的连接调用来证明。但我适当地编译和链接所以我假设C ++ 11功能正如我预期的那样工作。有人有想法吗?

编辑:

我使用的是Qt5.2.0 MinGW OpenGL。我正在使用Qt5.2.0附带的MinGW,即MinGW48 32.我正在编译库,iris,与我的应用程序同时使用cmake进行automoc,将其设置为链接依赖项,并包含正确的头。

EDIT2:包括我的所有连接电话。

1 个答案:

答案 0 :(得分:7)

原来我的窗户开发缺乏结果让我咬了屁股。因此对于Windows,如果要在Windows上导出符号,则需要包含这个奇怪的语句“__declspec(dllexport)”。

所以我做的是我添加了

/**
 * @brief Allows for windows exported symbols
 *
 * Windows requries a special modifier to allow them to export correctly.
 * This macro allows that while leaving Mac OS X and Linux alone.
 *
 * While Qt can tell us if it was make for WIN32, MAC, or LINUX, It cannot
 * tell us if we are being statically or dynamically linked. That is why
 * this is using the CMake variables instead of Qt
 */
#if defined (_WIN32)
  // cmake makes this variable if your a shared library (projectname_EXPORTS)
  #if defined(iris_EXPORTS)
    #define IRIS_EXPORT Q_DECL_EXPORT
  #else
    #define IRIS_EXPORT Q_DECL_IMPORT
  #endif /* iris_EXPORTS */
#else /* defined (_WIN32) */
 #define IRIS_EXPORT
#endif

然后我会在每个

上使用它
class IRIS_EXPORT ClassNameHere { ... }
IRIS_EXPORT void StaticFunctionNameHere(){...}

这解决了我的问题。

有关此问题的详细信息,请转到hereherehere