Creating a basic COM object



  • I am trying to make a basic COM object for some .Net code to call, and it isn't working out too well. I have done a LOT of ATL COM development, so I understand COM pretty well. When referencing the COM object, VS2008 is seeing the interface correctly and is able to create the object. When the method is called (either via the interface or via reflection), it errors out with:

    Member not found. (Exception from HRESULT: 0x80020003 (DISP_E_MEMBERNOTFOUND))

    So here is the code:

    SalesCenterHttpClient.h
    @#include <QObject>
    #include <QNetworkAccessManager>
    #include <QUrl>

    QT_BEGIN_NAMESPACE
    class QSslError;
    class QAuthenticator;
    class QNetworkReply;
    QT_END_NAMESPACE

    class SalesCenterHttpClient : public QObject
    {
    Q_OBJECT

    public:
    explicit SalesCenterHttpClient(QObject *parent = 0);

    Q_INVOKABLE void downloadContent( const QString& urlText );
    void downloadContent( const QUrl& urlText );
    Q_INVOKABLE int waitForDownloadContent( const QString& urlText );
    int waitForDownloadContent( const QUrl& urlText );
    Q_INVOKABLE QString errorMessage() const;
    Q_INVOKABLE int error() const;
    Q_INVOKABLE const QByteArray& content() const;
    Q_INVOKABLE void clear();

    private slots:
    void cancelDownload();
    void httpFinished();
    void httpReadyRead();
    void updateDataReadProgress(qint64 bytesRead, qint64 totalBytes);
    void slotAuthenticationRequired(QNetworkReply*,QAuthenticator );
    #ifndef QT_NO_OPENSSL
    void sslErrors(QNetworkReply
    ,const QList<QSslError> &errors);
    #endif

    signals:
    void readBytes(qint64 bytesRead, qint64 totalBytes);
    void finished();

    private:
    QUrl _url;
    QNetworkAccessManager _qnam;
    QNetworkReply *_reply;
    QByteArray _data;
    int _httpGetId;
    bool _httpRequestAborted;
    bool _ready;
    QString _errorMsg;
    int _errorCode;
    int _httpStatusCode;

    void startRequest(QUrl url);
    void setError( const QString& msg, int code );
    };@

    The cpp file will be in the first reply...



  • SalesCenterHttpClient.cpp
    @#include <QtNetwork>
    #include <ActiveQt/QAxFactory>

    QAXFACTORY_DEFAULT(SalesCenterHttpClient,
    "{88A5EF8E-A926-4eca-AE9C-9AAEBA7C1ACD}",
    "{06EC5DCF-EE32-4ce8-9F84-A717440C45E7}",
    "{478050B5-1787-4997-ADF2-F12B4BFB828D}",
    "{EA660B4F-505E-4d70-8356-D56814B8F5B3}",
    "{F3E80B9F-3512-4c64-BA77-69881CEAD399}")

    SalesCenterHttpClient::SalesCenterHttpClient(QObject *parent) : QObject(parent)
    {
    _httpRequestAborted = false;
    _ready = true;

    connect(&_qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
    this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*)));
    #ifndef QT_NO_OPENSSL
    connect(&_qnam, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
    this, SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
    #endif
    _errorCode = 0;
    }

    void SalesCenterHttpClient::clear()
    {
    _data.clear();
    _httpRequestAborted = true;
    _ready = true;
    }

    void SalesCenterHttpClient::startRequest(QUrl url)
    {
    setError("",0);
    _reply = _qnam.get(QNetworkRequest( _url));
    connect(_reply, SIGNAL(finished()), this, SLOT(httpFinished()));
    connect(_reply, SIGNAL(readyRead()), this, SLOT(httpReadyRead()));
    connect(_reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(updateDataReadProgress(qint64,qint64)));
    }

    void SalesCenterHttpClient::downloadContent( const QString& urlText )
    {
    downloadContent( QUrl(urlText));
    }

    void SalesCenterHttpClient::downloadContent( const QUrl& urlText )
    {
    if (!_ready)
    cancelDownload();
    _data.clear();
    _url = urlText;
    // schedule the request
    _httpRequestAborted = false;
    _ready = false;
    startRequest(_url);
    }

    /*! Start download with wait event loop until the download is completed. */
    int SalesCenterHttpClient::waitForDownloadContent( const QString& urlText )
    {
    return waitForDownloadContent( QUrl(urlText));
    }

    int SalesCenterHttpClient::waitForDownloadContent( const QUrl& urlText )
    {
    _httpStatusCode = 0;

    downloadContent(urlText);
    while(!_ready)
    QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);

    return _httpStatusCode;
    }

    void SalesCenterHttpClient::cancelDownload()
    {
    setError( tr("Download canceled."), -2 );
    _httpRequestAborted = true;
    _ready = true;
    _reply->abort();
    }

    void SalesCenterHttpClient::httpFinished()
    {
    if (_httpRequestAborted) {
    _data.clear();
    _reply->deleteLater();
    return;
    }

    _httpStatusCode = _reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    QVariant redirectionTarget = _reply->attribute(QNetworkRequest::RedirectionTargetAttribute);

    qDebug() << redirectionTarget;

    if (_reply->error())
    {
    _data.clear();
    setError( tr("Download failed: %1.").arg(_reply->errorString()), -1 );
    }
    else if (redirectionTarget.isValid())
    {
    QUrl newUrl = _url.resolved(redirectionTarget.toUrl());
    qDebug() << newUrl;
    if (newUrl != _url)
    {
    // handle redirection
    _url = newUrl;
    _reply->deleteLater();
    _data.clear();
    startRequest(_url);
    return;
    }
    }
    else
    {
    }

    _reply->deleteLater();
    _reply = 0;
    _ready = true;
    emit finished();
    }

    void SalesCenterHttpClient::setError(const QString &msg, int code)
    {
    _errorMsg = msg;
    _errorCode = code;
    }

    void SalesCenterHttpClient::httpReadyRead()
    {
    // this slot gets called everytime the QNetworkReply has new data.
    // We read all of its new data and write it into the file.
    // That way we use less RAM than when reading it at the finished()
    // signal of the QNetworkReply
    _data.append(_reply->readAll());
    }

    void SalesCenterHttpClient::updateDataReadProgress(qint64 bytesRead, qint64 totalBytes)
    {
    if (_httpRequestAborted)
    return;
    emit readBytes( bytesRead, totalBytes);
    }

    void SalesCenterHttpClient::slotAuthenticationRequired( QNetworkReply*, QAuthenticator *auth)
    {
    //setError( tr("Authentication required: %1 at %2").arg(authenticator->realm()).arg(url.host()), -3 );
    auth->setUser("<username>");
    auth->setPassword("<password>");
    }

    QString SalesCenterHttpClient::errorMessage() const
    {
    return _errorMsg;
    }

    int SalesCenterHttpClient::error() const
    {
    return _errorCode;
    }

    #ifndef QT_NO_OPENSSL
    void SalesCenterHttpClient::sslErrors(QNetworkReply*,const QList<QSslError> &errors)
    {
    QString errorString;
    foreach (const QSslError &error, errors) {
    if (!errorString.isEmpty())
    errorString += ", ";
    errorString += error.errorString();
    }
    setError( tr("One or more SSL errors has occurred: %1").arg(errorString), -4 );
    }
    #endif

    const QByteArray& SalesCenterHttpClient::content() const
    {
    return _data;
    }@



  • Sorry, I have no idea on it. I'm not sure if this can give you a little help. I useally use QAxContainer to process Com involved issues


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.