2012-05-14 6 views
1
#include <QtCore/QCoreApplication> 
#include <QTCore> 
#include <QtNetwork> 
#include <QDebug> 

#define CONNECT(sndr, sig, rcvr, slt) connect(sndr, SIGNAL(sig), rcvr, SLOT(slt)) 

class mynet : QObject 
{ 
    Q_OBJECT 

public: 
    mynet() 
    {} 

    void start() 
    { 
     CONNECT(tcpServer,  newConnection(),      this, acceptConnection()); 
     CONNECT(tcpClient,  connected(),       this, startTransfer()); 
     CONNECT(tcpClient,  bytesWritten(qint64),    this, updateClientProgress(qint64)); 
     CONNECT(tcpClient,  error(QAbstractSocket::SocketError), this, displayError(QAbstractSocket::SocketError)); 

     // start server listening 
     tcpServer->listen(); 
     while(!tcpServer->isListening()); 

     // make client connection 
     tcpClient->connectToHost(QHostAddress::LocalHost, tcpServer->serverPort()); 
    } 

public slots: 
    void acceptConnection() 
    { 
     tcpServerConnection = tcpServer->nextPendingConnection(); 
     CONNECT(tcpServerConnection, readyRead(), this, updateServerProgress()); 
     CONNECT(tcpServerConnection, error(QAbstractSocket::SocketError), this, displayError(QAbstractSocket)); 
     tcpServer->close(); 
    } 

    void startTransfer() 
    { 
     bytesToWrite = TotalBytes - (int)tcpClient->write(QByteArray(PayloadSize, '@')); 
    } 

    void updateServerProgress() 
    { 
     bytesReceived += (int)tcpServerConnection->bytesAvailable(); 
     tcpServerConnection->readAll(); 

     if (bytesReceived == TotalBytes) 
     { 
      qDebug() << "done"; 
      tcpServerConnection->close(); 
     } 
    } 

    void updateClientProgress(qint64 numBytes) 
    { 
     // callen when the TCP client has written some bytes 
     bytesWritten += (int)numBytes; 

     // only write more if not finished and when the Qt write buffer is below a certain size. 
     if (bytesToWrite > 0 && tcpClient->bytesToWrite() <= 4*PayloadSize) 
      bytesToWrite -= (int)tcpClient->write(QByteArray(qMin(bytesToWrite, PayloadSize), '@')); 
    } 

    void displayError(QAbstractSocket::SocketError socketError) 
    { 
     if (socketError == QTcpSocket::RemoteHostClosedError) 
      return; 

     qDebug() << tcpClient->errorString(); 


     tcpClient->close(); 
     tcpServer->close(); 
    } 

private: 
    QTcpServer* tcpServer; 
    QTcpSocket* tcpClient; 
    QTcpSocket* tcpServerConnection; 
    int bytesToWrite; 
    int bytesWritten; 
    int bytesReceived; 
    int TotalBytes; 
    int PayloadSize; 
}; 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 

    mynet m1; 
    m1.start(); 

    return a.exec(); 
} 

私は単純なQTコンソールTCPアプリケーション。私は間違って何をしていますか?

Undefined symbols for architecture x86_64: 
"vtable for mynet", referenced from: 
    mynet::mynet() in main.o 
    mynet::~mynet()in main.o. 

を得る私が間違っているのものを教えてください。 Qtで何らかの理由でクラスのメソッド定義をインライン化できないのですか?

+3

私はそれをテストすることはできませんが、これは、あなたが 'QObject'から継承されたときに' public'キーワードを忘れるの問題がある可能性があります: 'クラスMYNET:クラスMYNET'対公共QObject':QObject' – tmpearce

+2

I mynetの定義を別のファイルに移動し、.hと.cppのヘッダと実装を分けてください。 – Kunal

+1

そして、実際にあなたのメンバーポインタをすべて初期化する必要があります... – Mat

答えて

0

2つのもの:

1)あなたはQObjectから一般に派生する必要があります。

2)moc'ingこのファイルをコンパイルして出力をリンクしていますか? Q_OBJECTマクロをインクルードしてmocしないと、そのようなエラーが発生します。

+0

を追加してみましょう。QObjectの継承をpublicに設定しました。きれいな地震をしてから地震を起こした。同じ問題。何かアドバイス? –

+0

'moc'ツールは実行されていますか?そのツールの出力は、プロジェクトの一部としてコンパイルされてビルドされていますか? (あなたはmoc_xxxxxxを持っているはずです。cpファイルのどこかに) – tmpearce

+0

ld:警告:オプション '-L/usr/local/pgsql/lib'にディレクトリが見つかりません。 ld:警告:オプション '-L/tmp/qt-stuff-85167/source /qt-everywhere-opensource-src-4.8.1/Desktop/Qt/4.8.1/gcc/lib ' ld:警告:オプション' -F/tmp/qt-stuff-85167/source/qtに対してディレクトリが見つかりませんでした。 -everywhere-opensource-src-4.8.1/Desktop/Qt/4.8.1/gcc/lib ' アーキテクチャx86_64の未定義シンボル: 「vynable for mynet」、参照先: mynet :: mynet()in main。 o mynet ::〜main.oのmynet() 注:vtableがないと、通常、最初の非インライン仮想メンバ関数に定義がありません。 –

1

あなたはとてもメタオブジェクトコンパイラはそれらをスキャンし、彼らはmoc'ingを必要とし、関連するスタブを生成うまくでき.PROファイルに

HEADERS += mynet.h 
SOURCES += mynet.cpp 

をあなたのクラスを追加する必要があります。

#include "foo.moc" 

この行はqmakeのを告げるとVS Qtはアドインファイルがあるべきこと:あなたは非常に最後に次の行を配置する必要があり、あなたのソースファイルがfoo.cpp命名されると仮定すると

+0

この例では、main.cppファイルにクラス定義と実装があります。はい、いい形ではありませんでしたが、これは私の本当のプログラムが成長した些細な例であるはずです。 mynet.hもnet.cppもなく、main.cpp上でMOCを実行する必要があります。 –

+0

QTは同じファイル内に定義と実装が似ていませんか? –

+0

明らかにそうではありません。私は独自の.cpp/.hファイルに私のネットクラスを移動し、うまくいきました。 –

1

moc経由で実行し、生成されたmocファイルの名前をfoo.mocにする必要があります。

Qtヘッダーの#include行にも問題があります。私は次の作業が見つかりました:

#include <QtCore/QCoreApplication> 
#include <QtNetwork/QTcpServer> 
#include <QtNetwork/QTcpSocket> 
+0

非常に良い情報です。 Kubaに感謝します。 –

1

.proファイルにネットワークを追加してください。これにより、ネットワークライブラリ関数への正しいリンクが作成されます。

QT  += core network 
関連する問題