This code is written in Borland C++Builder 6 using Indy 9:
void __fastcall TfrmMain::ServerConnect(TIdPeerThread *AThread)
{
BKUK_PACKET Pkt;
----------(Omission)---------------------------------------
//AThread->Connection->WriteBuffer(&Pkt,sizeof(BKUK_PACKET),1);
----------(Omission)---------------------------------------
}
The function named WriteBuffer()
is not found in Indy 10. Is there an equivalent function?
BKUK_PACKET
is a structure of about 1200 bytes.
typedef struct _BKUK_PACKET_
{
BYTE head[4];
WORD PayLoad;
WORD Length;
BYTE Data[1200];
WORD Ver;
BYTE tail[2];
}BKUK_PACKET;
I found the TIdIOHandler.Write(TIdBytes)
method when I was looking at the instruction manual for Indy 10.
I referred to the code that I told you before:
Is there an equivalent of Indy 9's ReadBuffer() in Indy 10?
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);
}
But when I tried to program as above, I get an error:
[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
Please tell me how to fix this code.
You are not calling PopulateWriteBuffer()
at all, you are calling some other function named Populate02()
instead. Assuming that is just a typo and you really meant PopulateWriteBuffer()
, you are passing it a pointer to a BKUK_PACKET
but it takes a reference to a BKUK_PACKET
instead.
Change
Populate02(&Pkt, AContext->Connection->IOHandler);
To
PopulateWriteBuffer(Pkt, AContext->Connection->IOHandler);
That being said, the TIdIOHandler::Write(TIdBytes)
method will work just fine, you just need to copy your BKUK_PACKET
variable into an intermediate TIdBytes
variable first, such as with Indy's RawToBytes()
function, eg:
void __fastcall TfrmMain::ServerConnect(TIdContext *AContext)
{
BKUK_PACKET Pkt;
// populate Pkt as needed...
AContext->Connection->IOHandler->Write(RawToBytes(&Pkt, sizeof(BKUK_PACKET)));
}
Alternatively, you can use the TIdIOHandler::Write(TStream*)
method with a TIdMemoryBufferStream
to send directly from your BKUK_PACKET
variable without making a copy of its data first, similar to Indy 9's WriteBuffer()
, eg:
#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());
}