Indy 10 中是否有与 Indy 9 的 WriteBuffer() 等效的东西?

Is there an equivalent of Indy 9's WriteBuffer() in Indy 10?

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

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

//AThread->Connection->WriteBuffer(&Pkt,sizeof(BKUK_PACKET),1);

----------(Omission)---------------------------------------
}

在 Indy 10 中找不到名为 WriteBuffer() 的函数。是否有等效函数?

BKUK_PACKET是一个1200字节左右的结构

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

我在看 Indy 10 的说明手册时找到了 TIdIOHandler.Write(TIdBytes) 方法。

我参考了我之前告诉你的代码:

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

----------(Omission)---------------------------------------

Populate02(&Pkt,AContext->Connection->IOHandler);
}

但是当我尝试按上述方式编程时,出现错误:

[bcc32c error] Main.cpp(608): no matching function for call to 'Populate02'

Main.cpp(478): candidate function [with T = _BKUK_PACKET_ *] not viable: no known conversion from '_PACKET *' (aka '_BKUK_PACKET_ *') to '_BKUK_PACKET_ *&' for 1st argument

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

您根本没有调用 PopulateWriteBuffer(),而是调用了另一个名为 Populate02() 的函数。假设这只是一个拼写错误,而您的意思是 PopulateWriteBuffer(),您将 指针 传递给 BKUK_PACKET 但它需要一个 引用 改为 BKUK_PACKET

改变

Populate02(&Pkt, AContext->Connection->IOHandler);

PopulateWriteBuffer(Pkt, AContext->Connection->IOHandler);

也就是说,TIdIOHandler::Write(TIdBytes) 方法会工作得很好,您只需要先将 BKUK_PACKET 变量复制到中间 TIdBytes 变量中,例如 Indy 的 RawToBytes()函数,例如:

void __fastcall TfrmMain::ServerConnect(TIdContext *AContext)
{
    BKUK_PACKET Pkt;
    // populate Pkt as needed...

    AContext->Connection->IOHandler->Write(RawToBytes(&Pkt, sizeof(BKUK_PACKET)));
}

或者,您可以使用带有 TIdMemoryBufferStreamTIdIOHandler::Write(TStream*) 方法直接从您的 BKUK_PACKET 变量发送数据,而无需先复制其数据,类似于 Indy 9 的 WriteBuffer(),例如:

#include <memory>

void __fastcall TfrmMain::ServerConnect(TIdContext *AContext)
{
    BKUK_PACKET Pkt;
    // populate Pkt as needed...

    std::unique_ptr<TIdMemoryBufferStream> strm(new TIdMemoryBufferStream(&Pkt, sizeof(BKUK_PACKET)));
    // or std::auto_ptr prior to C++11...

    AContext->Connection->IOHandler->Write(strm.get());
}