I am working on a project for my job to encode/decode into buffers DNS Records objects in C++. Some records have the same infos, so I created a class Dns message with theses basic infos:
class CDnsMessage { public: CDnsMessage(); virtual ~CDnsMessage(); virtual int GetSize() = 0; uint32_t m_ttl; DnsClass dclass; DnsType type; std::string m_domain; };
The DnsClass
and DnsTypes
are enum with the differents class/types I use. Then I have my sub-classes for each record, I will take A for the example:
class CDns_RR_A : public CDnsMessage { public: CDns_RR_A(); virtual ~CDns_RR_A(); virtual int GetSize(CDnsMessage const& msg); uint32_t m_address; };
Then I have my encode/decode function in another header, encoder.h
and encoder.cpp
.
I am receiving a DnsMessage
(the object) and receiving buffer, and I encode or decode. So I used dynamic cast to know which type of record it is, and adapt the encode and decode to the variables the object has.
here is my decode for example:
EncodeResult DecodeData(const char * buffer,CDnsMessage & msg,std::size_t size) { EncodeResult res(ENCODE_OK); uint32 ttl = 0; eDnsClass dnsclass; eDnsType dnstype; //decoding RR_A if(CDns_RR_A* RR_A_msg = dynamic_cast< CDns_RR_A* >( &msg )) { uint32_t address; dnsclass = CLASS_IN; msg.dclass = dnsclass; dnstype = TYPE_A; msg.type = dnstype; res = DecodeInt32(&buffer,&size,&ttl); CHECK_DECODE_ERROR(res); msg.m_ttl = ttl; res = DecodeInt32(&buffer,&size,&address); CHECK_DECODE_ERROR(res); msg.m_address = address; } }
The DecodeInt32
is a function made by people before long time ago, it takes a buffer (char**
), a size_t*
and a uint32
.
I have two problems, first I can’t access the members of my subclass, when I compile I got a problem with msg.dclass or msg.type and It says “request for member ‘class’ in ‘RR_A_msg’, which is of non-class type ‘CDns_RR_A*’ but I don’t understand, if my dynamic cast works it mean that the msg received waiting to be fulfilled is of type A no?
And my second problem is: I am using uint32_t
for the ttl (imposed by enterprise) and my decodeint32
takes uint32
so the compiler says invalid conversion from uint32_t* to uint32
.
Is there away to convert one to another?
Edit: Updated my code following answers and advices, now i have
if(dynamic_cast< CDns_RR_A* >( &msg ) != nullptr) { CDns_RR_A* RR_A_msg = dynamic_cast< CDns_RR_A* >( &msg ) uint32 address; dnsclass = CLASS_IN; RR_A_msg->dclass = dnsclass; dnstype = TYPE_A; RR_A_msg->type = dnstype; res = DecodeInt32(&buffer,&size,&ttl); CHECK_DECODE_ERROR(res); RR_A_msg->m_ttl = ttl; res = DecodeInt32(&buffer,&size,&address); CHECK_DECODE_ERROR(res); RR_A_msg->m_address = address; }
Changing uint32_t to uint32 for decode worked, and having RR_A_msg-> instead of msg. worked too.
But now i have undefined reference to
typeinfo for CDns_RR_A’`
Advertisement
Answer
For the “you cannot convert uint32_t* to uint32” the issue is that the former is a pointer and the later is not. You should take the & off the front and pass the value not a pointer to it.
I don’t know why you can’t get the class member (maybe related to using a reserved name as a variable?) but you shouldn’t be able to access m_address in this way.
Instead of
msg.m_address
You need to be using
RR_A_msg->m_address