1

我已经阅读了过去 1 小时以上未解决的外部符号错误,并尝试修复我的错误,但我认为是时候让我重新审视一下这个问题了。

我正在使用来自 Interactivebrokers.com 的 API 在 QT 中构建一个交易程序。

API有一个虚拟类EWrapper,我从一个类继承EWrapperSubclass

在我的文章EWrapperSubclass.cpp中,我已经使用所需的EWrapperSubclass::Method语法定义了所有内容,以确保Method引用该类的方法。

在我的 IBProject.cpp 中,我有一个简单的EWrapper变量指向new EWrapperSubclass. 那就是发生未解决的外部符号错误的地方。我得到错误:

LNK2019: unresolved external symbol "public: __cdecl EWrapperSubclass::EWrapperSubclass(void)" (??0EWrapperSubclass@@QEAA@XZ) referenced in function "public: __cdecl IBProject::IBProject(class QWidget *)" (??0IBProject@@QEAA@PEAVQWidget@@@Z)

有人可以告诉我我可能做错了什么吗?

EWrapperSubclass.h

#ifndef EWRAPPERSUBCLASS_H
#define EWRAPPERSUBCLASS_H
#include "Shared/EWrapper.h"
class EClientSocket;
class EWrapperSubclass : public EWrapper
{
public:
    EWrapperSubclass();
    ~EWrapperSubclass();
    EClientSocket *pEClientSocket;

    ...//various methods declared here with void methodname
 }

EWrapperSubclass.cpp

#include "Shared/EWrapper.h"
#include "ewrappersubclass.h"
#include "SocketClient/src/EClientSocket.h"

EWrapperSubclass::EWrapperSubclass()
{
    pEClientSocket = new EClientSocket(this);
    pEClientSocket->eConnect("127.0.0.1",4001,0);
    connect(this,SIGNAL(disconnected()),this,SLOT(reconnect());
}

EWrapperSubclass::~EWrapperSubclass(){
    pEClientSocket->eDisconnect();
    delete pEClientSocket;
}

void EWrapperSubclass::isConnected(){
    return pEClientSocket->isConnected();
}

...//various methods defined here as void EWrapperSubclass::Methodname

IB项目.h

#ifndef IBPROJECT_H
#define IBPROJECT_H

#include <QMainWindow>
#include "Shared/EWrapper.h"
#include "ewrappersubclass.h"


namespace Ui {
    class IBProject;
}

class EWrapper;
class EWrapperSubclass;
class IBProject : public QMainWindow
{
Q_OBJECT

public:
    explicit IBProject(QWidget *parent = 0);
    ~IBProject();

private:
    Ui::IBProject *ui;
    EWrapper *pewrapper;
};

#endif // IBPROJECT_H

IB项目.cpp

#include "ibproject.h"
#include "ui_ibproject.h"

IBProject::IBProject(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::IBProject)
{
    ui->setupUi(this);

    pewrapper = new EWrapperSubclass;

    connect(ui->tradeButton,SIGNAL(clicked()),this,SLOT(on_tradeButton_clicked()));
    connect(pewrapper,SIGNAL(connected()),this,SLOT(on_connected));
    connect(pewrapper,SIGNAL(disconnected()),this,SLOT(on_disconnected));
}

IBProject::~IBProject()
{
    delete ui;
    delete pewrapper;
}
4

1 回答 1

0

PosixTestClient.h

#ifndef posixtestclient_h__INCLUDED
#define posixtestclient_h__INCLUDED

#include "EWrapper.h"

#include <memory>
#include <stdio.h> //printf()

namespace IB {

class EPosixClientSocket;

enum State {
    ST_CONNECT,
    ST_PLACEORDER,
    ST_PLACEORDER_ACK,
    ST_CANCELORDER,
    ST_CANCELORDER_ACK,
    ST_PING,
    ST_PING_ACK,
    ST_IDLE
};


class PosixTestClient : public EWrapper
{
public:

    PosixTestClient();
    ~PosixTestClient();

    void processMessages();

public:

    bool connect(const char * host, unsigned int port, int clientId = 0);
    void disconnect() const;
    bool isConnected() const;

private:

    void reqCurrentTime();
    void placeOrder();
    void cancelOrder();

public:
    // events
    void tickPrice(TickerId tickerId, TickType field, double price, int canAutoExecute);
    void tickSize(TickerId tickerId, TickType field, int size);
    void tickOptionComputation( TickerId tickerId, TickType tickType, double impliedVol, double delta,
        double optPrice, double pvDividend, double gamma, double vega, double theta, double undPrice);
    void tickGeneric(TickerId tickerId, TickType tickType, double value);
    void tickString(TickerId tickerId, TickType tickType, const IBString& value);
//... etc

private:

    std::auto_ptr<EPosixClientSocket> m_pClient;
    State m_state;
    time_t m_sleepDeadline;

    OrderId m_orderId;
};

}

实现,PosixTestClient.cpp

#include "PosixTestClient.h"

#include "EPosixClientSocket.h"
/* In this example we just include the platform header to have select(). In real
   life you should include the needed headers from your system. */
#include "EPosixClientSocketPlatform.h"

#include "Contract.h"
#include "Order.h"

#include <time.h>
#include <sys/time.h>

#if defined __INTEL_COMPILER
# pragma warning (disable:869)
#elif defined __GNUC__
# pragma GCC diagnostic ignored "-Wswitch"
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif  /* __INTEL_COMPILER */

namespace IB {

const int PING_DEADLINE = 2; // seconds
const int SLEEP_BETWEEN_PINGS = 30; // seconds

///////////////////////////////////////////////////////////
// member funcs
PosixTestClient::PosixTestClient()
    : m_pClient(new EPosixClientSocket(this))
    , m_state(ST_CONNECT)
    , m_sleepDeadline(0)
    , m_orderId(0)
{
}

PosixTestClient::~PosixTestClient()
{
}

bool PosixTestClient::connect(const char *host, unsigned int port, int clientId)
{
    // trying to connect
    printf( "Connecting to %s:%u clientId:%d\n", !( host && *host) ? "127.0.0.1" : host, port, clientId);

    bool bRes = m_pClient->eConnect2( host, port, clientId);

    if (bRes) {
        printf( "Connected to %s:%u clientId:%d\n", !( host && *host) ? "127.0.0.1" : host, port, clientId);
    }
    else
        printf( "Cannot connect to %s:%u clientId:%d\n", !( host && *host) ? "127.0.0.1" : host, port, clientId);

    return bRes;
}

void PosixTestClient::disconnect() const
{
    m_pClient->eDisconnect();

    printf ( "Disconnected\n");
}

bool PosixTestClient::isConnected() const
{
    return m_pClient->isConnected();
}

void PosixTestClient::processMessages()
{
//...
}

//////////////////////////////////////////////////////////////////
// methods
void PosixTestClient::reqCurrentTime()
{
    printf( "--> Requesting Current Time2\n");

    // set ping deadline to "now + n seconds"
    m_sleepDeadline = time( NULL) + PING_DEADLINE;

    m_state = ST_PING_ACK;

    m_pClient->reqCurrentTime();
}

//...etc

///////////////////////////////////////////////////////////////////
// events
void PosixTestClient::orderStatus( OrderId orderId, const IBString &status, int filled,
       int remaining, double avgFillPrice, int permId, int parentId,
       double lastFillPrice, int clientId, const IBString& whyHeld)

{}

void PosixTestClient::error(const int id, const int errorCode, const IBString errorString)
{
    printf( "Error id=%d, errorCode=%d, msg=%s\n", id, errorCode, errorString.c_str());

    if( id == -1 && errorCode == 1100) // if "Connectivity between IB and TWS has been lost"
        disconnect();
}

void PosixTestClient::tickPrice( TickerId tickerId, TickType field, double price, int canAutoExecute) {}
void PosixTestClient::tickSize( TickerId tickerId, TickType field, int size) {}
void PosixTestClient::tickOptionComputation( TickerId tickerId, TickType tickType, double impliedVol, double delta,
                                             double optPrice, double pvDividend,
                                             double gamma, double vega, double theta, double undPrice) {}
void PosixTestClient::tickGeneric(TickerId tickerId, TickType tickType, double value) {}
void PosixTestClient::tickString(TickerId tickerId, TickType tickType, const IBString& value) {}
void PosixTestClient::tickEFP(TickerId tickerId, TickType tickType, double basisPoints, const IBString& formattedBasisPoints,
                               double totalDividends, int holdDays, const IBString& futureExpiry, double dividendImpact, double dividendsToExpiry) {}
void PosixTestClient::openOrder( OrderId orderId, const Contract&, const Order&, const OrderState& ostate) {}
void PosixTestClient::openOrderEnd() {}
void PosixTestClient::winError( const IBString &str, int lastError) {}
void PosixTestClient::connectionClosed() {}
void PosixTestClient::updateAccountValue(const IBString& key, const IBString& val,
                                          const IBString& currency, const IBString& accountName) {}
void PosixTestClient::updatePortfolio(const Contract& contract, int position,
        double marketPrice, double marketValue, double averageCost,
        double unrealizedPNL, double realizedPNL, const IBString& accountName){}
void PosixTestClient::updateAccountTime(const IBString& timeStamp) {}
void PosixTestClient::accountDownloadEnd(const IBString& accountName) {}
void PosixTestClient::contractDetails( int reqId, const ContractDetails& contractDetails) {}
void PosixTestClient::bondContractDetails( int reqId, const ContractDetails& contractDetails) {}
void PosixTestClient::contractDetailsEnd( int reqId) {}
void PosixTestClient::execDetails( int reqId, const Contract& contract, const Execution& execution) {}
void PosixTestClient::execDetailsEnd( int reqId) {}

void PosixTestClient::updateMktDepth(TickerId id, int position, int operation, int side,
                                      double price, int size) {}
void PosixTestClient::updateMktDepthL2(TickerId id, int position, IBString marketMaker, int operation,
                                        int side, double price, int size) {}
void PosixTestClient::updateNewsBulletin(int msgId, int msgType, const IBString& newsMessage, const IBString& originExch) {}
void PosixTestClient::managedAccounts( const IBString& accountsList) {}
void PosixTestClient::receiveFA(faDataType pFaDataType, const IBString& cxml) {}
void PosixTestClient::historicalData(TickerId reqId, const IBString& date, double open, double high,
                                      double low, double close, int volume, int barCount, double WAP, int hasGaps) {}
void PosixTestClient::scannerParameters(const IBString &xml) {}
void PosixTestClient::scannerData(int reqId, int rank, const ContractDetails &contractDetails,
       const IBString &distance, const IBString &benchmark, const IBString &projection,
       const IBString &legsStr) {}
void PosixTestClient::scannerDataEnd(int reqId) {}
void PosixTestClient::realtimeBar(TickerId reqId, long time, double open, double high, double low, double close,
                                   long volume, double wap, int count) {}
void PosixTestClient::fundamentalData(TickerId reqId, const IBString& data) {}
void PosixTestClient::deltaNeutralValidation(int reqId, const UnderComp& underComp) {}
void PosixTestClient::tickSnapshotEnd(int reqId) {}
void PosixTestClient::marketDataType(TickerId reqId, int marketDataType) {}

}

并在 main 中使用它:

#ifdef _WIN32
# include <windows.h>
# define sleep( seconds) Sleep( seconds * 1000);
#else
# include <unistd.h>
#endif

#include "PosixTestClient.h"

const unsigned MAX_ATTEMPTS = 1;
const unsigned SLEEP_TIME = 10;

int main(int argc, char** argv)
{
    IB::PosixTestClient client;
        client.connect( host, port, clientId);
        //...
}
于 2013-04-27T17:59:15.310 回答