-1

此代码是使用 Indy 9 在 Borland C++Builder 6 中编写的:

void __fastcall TfrmMain::ServerConnect(TIdPeerThread *AThread)
{
     BKUK_PACKET Pkt;
----------(中略)---------------------------------------

AThread->Connection->ReadBuffer((BYTE *)&Pkt,sizeof(BKUK_PACKET));

----------(中略)---------------------------------------
}

ReadBuffer()在 Indy 10 中找不到命名的函数。有等效的函数吗?

BKUK_PACKET是一个大约1200字节的结构。

typedef struct _BKUK_PACKET_
{
    BYTE head[4];
    WORD PayLoad;
    WORD Length;
    BYTE Data[1200];
    WORD Ver;
    BYTE tail[2];
}BKUK_PACKET;

ReadBytes()在查看 Indy 10 的说明手册时发现。但是当我尝试如下编程时,出现错误:

Context->Connection->IOHandler->ReadBytes((BYTE *)&Pkt,sizeof(BKUK_PACKET))

[bcc32c 错误] Main.cpp(530):对类型“Idglobal::TIdBytes”(又名“DynamicArray<unsigned char>”)的非 const 左值引用无法绑定到“BYTE *”类型的临时变量(又名“无符号字符” *')

IdIOHandler.hpp(235):在此处将参数传递给参数“VBuffer”

请告诉我如何修复此代码。

4

2 回答 2

2

的签名ReadBytes()

virtual void __fastcall ReadBytes(Idglobal::TIdBytes &VBuffer, 
                                  int AByteCount,
                                  bool AAppend = true);

TIdBytesReadBytes()如果您想在Pkt不使用中间变量的情况下进行填充,则动态性质不是一个好的选择。

但是,您可以使用TIdIOHandler's

System::Byte __fastcall ReadByte();

并创建自己的函数来填充对象:

template<typename T>
void __fastcall Populate(T& obj, TIdIOHandler* ioh) {
    System::Byte* p = (System::Byte*) &obj;
    for(unsigned count=0; count<sizeof(T); ++count, ++p)
        *p = ioh->ReadByte();
}

并像这样使用它:

BKUK_PACKET Pkt;
Populate(Pkt, Context->Connection->IOHandler);
于 2019-12-01T13:58:20.067 回答
1

TIdIOHandler::ReadBytes()方法可以正常工作,您只需TIdBytes要先使用一个中间变量来读取,然后您可以将该数据复制到您的BKUK_PACKET变量中,例如使用 Indy 的BytesToRaw()函数,例如:

void __fastcall TfrmMain::ServerConnect(TIdContext *AContext)
{
    BKUK_PACKET Pkt;

    TIdBytes bytes;
    AContext->Connection->IOHandler->ReadBytes(bytes, sizeof(BKUK_PACKET));
    BytesToRaw(bytes, &Pkt, sizeof(BKUK_PACKET));

    // use Pkt as needed...
}

或者,您可以使用TIdIOHandler::ReadStream()带有 a 的方法TIdMemoryBufferStream直接读入您的BKUK_PACKET变量,类似于 Indy 9's ReadBuffer(),例如:

#include <memory>

void __fastcall TfrmMain::ServerConnect(TIdContext *AContext)
{
    BKUK_PACKET Pkt;

    std::unique_ptr<TIdMemoryBufferStream> strm(new TIdMemoryBufferStream(&Pkt, sizeof(BKUK_PACKET)));
    // or std::auto_ptr prior to C++11...
    AContext->Connection->IOHandler->ReadStream(strm.get(), sizeof(BKUK_PACKET), false);

    // use Pkt as needed...
}
于 2019-12-02T05:01:18.563 回答