首页 > 解决方案 > 盈透证券 C++ 错误:错误:未在此范围内声明“min”

问题描述

我正在尝试在 Ubuntu (18.04) 上设置Interactive Brokers API 。我已经安装了用于与交易所通信的 IB 网关,以及用于开发 Java、C++、C# 和 Python 交易算法的其他 API 软件。(你可以在这里找到)。该 API 是用 Java 和 C++ 编写的,并且如前所述,它提供对两者的支持。但是,当尝试从其源代码编译示例时,EReader.cpp 文件中出现错误。我已经在他们的代码中处理了其他几个 C++ 错误,但是我无法弄清楚这一点。这是代码:

#include "StdAfx.h"
#include "shared_ptr.h"
#include "Contract.h"
#include "EDecoder.h"
#include "EMutex.h"
#include "EReader.h"
#include "EClientSocket.h"
#include "EPosixClientSocketPlatform.h"
#include "EReaderSignal.h"
#include "EMessage.h"
#include "DefaultEWrapper.h"

#define IN_BUF_SIZE_DEFAULT 8192

static DefaultEWrapper defaultWrapper;

EReader::EReader(EClientSocket *clientSocket, EReaderSignal *signal)
: processMsgsDecoder_(clientSocket->EClient::serverVersion(), clientSocket->getWrapper(), clientSocket) {
    m_isAlive = true;
    m_pClientSocket = clientSocket;       
    m_pEReaderSignal = signal;
    m_needsWriteSelect = false;
    m_nMaxBufSize = IN_BUF_SIZE_DEFAULT;
    m_buf.reserve(IN_BUF_SIZE_DEFAULT);
}

EReader::~EReader(void) {
m_isAlive = false;

#if defined(IB_WIN32)
WaitForSingleObject(m_hReadThread, INFINITE);
#endif
}

void EReader::checkClient() {
m_needsWriteSelect = !m_pClientSocket->getTransport()- 
isOutBufferEmpty();
}

void EReader::start() {
#if defined(IB_POSIX)
pthread_t thread;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create( &thread, &attr, readToQueueThread, this );
pthread_attr_destroy(&attr);
#elif defined(IB_WIN32)
m_hReadThread = CreateThread(0, 0, readToQueueThread, this, 0, 0);
#else
#   error "Not implemented on this platform"
#endif
}

#if defined(IB_POSIX)
void * EReader::readToQueueThread(void * lpParam)
#elif defined(IB_WIN32)
DWORD WINAPI EReader::readToQueueThread(LPVOID lpParam)
#else
#   error "Not implemented on this platform"
#endif
{
EReader *pThis = reinterpret_cast<EReader *>(lpParam);

pThis->readToQueue();
return 0;
}

void EReader::readToQueue() {
EMessage *msg = 0;

while (m_isAlive) {
    if (m_buf.size() == 0 && !processNonBlockingSelect() && m_pClientSocket->isSocketOK())
        continue;

    if (!putMessageToQueue())
        break;
}

m_pClientSocket->handleSocketError();
m_pEReaderSignal->issueSignal(); //letting client know that socket was closed
}

bool EReader::putMessageToQueue() {
EMessage *msg = 0;

if (m_pClientSocket->isSocketOK())
    msg = readSingleMsg();

if (msg == 0)
    return false;

m_csMsgQueue.Enter();
m_msgQueue.push_back(ibapi::shared_ptr<EMessage>(msg));
m_csMsgQueue.Leave();
m_pEReaderSignal->issueSignal();

return true;
}

bool EReader::processNonBlockingSelect() {
fd_set readSet, writeSet, errorSet;
struct timeval tval;

tval.tv_usec = 100 * 1000; //100 ms
tval.tv_sec = 0;

if( m_pClientSocket->fd() >= 0 ) {

    FD_ZERO( &readSet);
    errorSet = writeSet = readSet;

    FD_SET( m_pClientSocket->fd(), &readSet);

    if (m_needsWriteSelect)
        FD_SET( m_pClientSocket->fd(), &writeSet);

    FD_SET( m_pClientSocket->fd(), &errorSet);

    int ret = select( m_pClientSocket->fd() + 1, &readSet, &writeSet, &errorSet, &tval);

    if( ret == 0) { // timeout
        return false;
    }

    if( ret < 0) {  // error
        m_pClientSocket->eDisconnect();
        return false;
    }

    if( m_pClientSocket->fd() < 0)
        return false;

    if( FD_ISSET( m_pClientSocket->fd(), &errorSet)) {
        // error on socket
        m_pClientSocket->onError();
    }

    if( m_pClientSocket->fd() < 0)
        return false;

    if( FD_ISSET( m_pClientSocket->fd(), &writeSet)) {
        // socket is ready for writing
        onSend();
    }

    if( m_pClientSocket->fd() < 0)
        return false;

    if( FD_ISSET( m_pClientSocket->fd(), &readSet)) {
        // socket is ready for reading
        onReceive();
    }

    return true;
}

return false;
}

void EReader::onSend() {
m_pEReaderSignal->issueSignal();
}

void EReader::onReceive() {
int nOffset = m_buf.size();

m_buf.resize(m_nMaxBufSize);

int nRes = m_pClientSocket->receive(m_buf.data() + nOffset, m_buf.size() - nOffset);

if (nRes <= 0)
    return;

m_buf.resize(nRes + nOffset);   
}

bool EReader::bufferedRead(char *buf, int size) {
while (size > 0) {
    while (m_buf.size() < size && m_buf.size() < m_nMaxBufSize)
        if (!processNonBlockingSelect() && !m_pClientSocket->isSocketOK())
            return false;

    int nBytes = (std::min<unsigned int>)(m_nMaxBufSize, size);



    std::copy(m_buf.begin(), m_buf.begin() + nBytes, buf);
    std::copy(m_buf.begin() + nBytes, m_buf.end(), m_buf.begin());
    m_buf.resize(m_buf.size() - nBytes);

    size -= nBytes;
    buf += nBytes;
}

return true;
}

EMessage * EReader::readSingleMsg() {
if (m_pClientSocket->usingV100Plus()) {
    int msgSize;

    if (!bufferedRead((char *)&msgSize, sizeof(msgSize)))
        return 0;

    msgSize = htonl(msgSize);

    if (msgSize <= 0 || msgSize > MAX_MSG_LEN)
        return 0;

    std::vector<char> buf = std::vector<char>(msgSize);

    if (!bufferedRead(buf.data(), buf.size()))
        return 0;

    return new EMessage(buf);
}
else {
    const char *pBegin = 0;
    const char *pEnd = 0;
    int msgSize = 0;

    while (msgSize == 0)
    {
        if (m_buf.size() >= m_nMaxBufSize * 3/4) 
            m_nMaxBufSize *= 2;

        if (!processNonBlockingSelect() && !m_pClientSocket->isSocketOK())
            return 0;

        pBegin = m_buf.data();
        pEnd = pBegin + m_buf.size();
        msgSize = EDecoder(m_pClientSocket->EClient::serverVersion(), &defaultWrapper).parseAndProcessMsg(pBegin, pEnd);
    }

    std::vector<char> msgData(msgSize);

    if (!bufferedRead(msgData.data(), msgSize))
        return 0;

    if (m_buf.size() < IN_BUF_SIZE_DEFAULT && m_buf.capacity() > IN_BUF_SIZE_DEFAULT)
    {
        m_buf.resize(m_nMaxBufSize = IN_BUF_SIZE_DEFAULT);
        m_buf.shrink_to_fit();
    }

    EMessage * msg = new EMessage(msgData);

    return msg;
}
}

ibapi::shared_ptr<EMessage> EReader::getMsg(void) {
m_csMsgQueue.Enter();

if (m_msgQueue.size() == 0) {
    m_csMsgQueue.Leave();

    return ibapi::shared_ptr<EMessage>();
}

ibapi::shared_ptr<EMessage> msg = m_msgQueue.front();

m_msgQueue.pop_front();
m_csMsgQueue.Leave();

return msg;
}


void EReader::processMsgs(void) {
m_pClientSocket->onSend();
checkClient();

ibapi::shared_ptr<EMessage> msg = getMsg();

if (!msg.get())
    return;

const char *pBegin = msg->begin();

while (processMsgsDecoder_.parseAndProcessMsg(pBegin, msg->end()) > 0) 
{
    msg = getMsg();

    if (!msg.get())
        break;

    pBegin = msg->begin();
} 
}

我得到的错误如下: 错误

error: 'min' was not declared in this scope  int nBytes = 
min(m_nMaxBuffSize, size);

我不得不做其他事情,例如编辑其他源代码和 makefile,我被困在这里。任何见解将不胜感激。

标签: c++interactive-brokers

解决方案


在我的版本 973 源代码中,我有

int nBytes = (std::min<unsigned int>)(m_nMaxBufSize, size);

确保您使用的是最新版本。问题可能是这里发生的事情的一个例子为什么“使用命名空间标准”被认为是不好的做法?


推荐阅读