Indy 10 中是否有与 Indy 9 的 ReadBuffer() 等效的东西?
Is there an equivalent of Indy 9's ReadBuffer() in Indy 10?
此代码是使用 Indy 9 在 Borland C++Builder 6 中编写的:
void __fastcall TfrmMain::ServerConnect(TIdPeerThread *AThread)
{
BKUK_PACKET Pkt;
----------(中略)---------------------------------------
AThread->Connection->ReadBuffer((BYTE *)&Pkt,sizeof(BKUK_PACKET));
----------(中略)---------------------------------------
}
在 Indy 10 中找不到名为 ReadBuffer()
的函数。是否有等效函数?
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 的说明手册时发现 ReadBytes()
。但是当我尝试如下编程时,出现错误:
Context->Connection->IOHandler->ReadBytes((BYTE *)&Pkt,sizeof(BKUK_PACKET))
[bcc32c error] Main.cpp(530): non-const lvalue reference to type 'Idglobal::TIdBytes' (aka 'DynamicArray<unsigned char>') cannot bind to a temporary of type 'BYTE *' (aka 'unsigned char *')
IdIOHandler.hpp(235): passing argument to parameter 'VBuffer' here
请告诉我如何修复此代码。
ReadBytes()
的签名是
virtual void __fastcall ReadBytes(Idglobal::TIdBytes &VBuffer,
int AByteCount,
bool AAppend = true);
如果您想在不使用中间变量的情况下填充 Pkt
,TIdBytes
动态特性使得 ReadBytes()
不是一个好的选择。
但是您可以使用 TIdIOHandler
的
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);
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...
}
或者,您可以使用带有 TIdMemoryBufferStream
的 TIdIOHandler::ReadStream()
方法直接读入您的 BKUK_PACKET
变量,类似于 Indy 9 的 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...
}
此代码是使用 Indy 9 在 Borland C++Builder 6 中编写的:
void __fastcall TfrmMain::ServerConnect(TIdPeerThread *AThread)
{
BKUK_PACKET Pkt;
----------(中略)---------------------------------------
AThread->Connection->ReadBuffer((BYTE *)&Pkt,sizeof(BKUK_PACKET));
----------(中略)---------------------------------------
}
在 Indy 10 中找不到名为 ReadBuffer()
的函数。是否有等效函数?
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 的说明手册时发现 ReadBytes()
。但是当我尝试如下编程时,出现错误:
Context->Connection->IOHandler->ReadBytes((BYTE *)&Pkt,sizeof(BKUK_PACKET))
[bcc32c error] Main.cpp(530): non-const lvalue reference to type 'Idglobal::TIdBytes' (aka 'DynamicArray<unsigned char>') cannot bind to a temporary of type 'BYTE *' (aka 'unsigned char *')
IdIOHandler.hpp(235): passing argument to parameter 'VBuffer' here
请告诉我如何修复此代码。
ReadBytes()
的签名是
virtual void __fastcall ReadBytes(Idglobal::TIdBytes &VBuffer,
int AByteCount,
bool AAppend = true);
如果您想在不使用中间变量的情况下填充 Pkt
,TIdBytes
动态特性使得 ReadBytes()
不是一个好的选择。
但是您可以使用 TIdIOHandler
的
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);
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...
}
或者,您可以使用带有 TIdMemoryBufferStream
的 TIdIOHandler::ReadStream()
方法直接读入您的 BKUK_PACKET
变量,类似于 Indy 9 的 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...
}