Convert class from C++ to Delphi - c++

I'm trying to convert a C++ project to Delphi, but I don't know how to convert these two classes:
class CData;
class CContext;
class CData
{
public:
CContext* Data;
};
class CContext
{
public:
char Unk[2240];
DWORD data1;
DWORD data2;
DWORD data3;
};
Usage:
CData* Data = (CData*)(0x00112233);
//This code obtain the bytes in memory of the address "0x00112233" based on the sizes specified at CContext class
Please, if someone knows, help-me.
Thank you.

The class is just a simple compound structure. That's a record in Delphi:
type
TData = record
unk: array [0..2240-1] of AnsiChar;
data1, data2, data3: DWORD;
end;
Your context type is just a pointer to that:
type
TContext =^TData;
In the C code this pointer is wrapped in a class which seems a little pointless to me.
Declare a variable that is a pointer to TContext:
var
context: ^TContext;
Assign it like this:
context := Pointer($00112233);

It looks like your CContext class is nothing more than a 2240 length string with 3 double-words of reserved space (likely that is never used). CData is nothing more than a pointer to an instance of CContext. To be more specific about how to port these, you would need to give more specifics on how they are used. As it stands right now, you could likely just implement a version of CData that has a string member.

Related

Nested array of structs - how do i properly assign a value to struct members?

I have
struct Voice {
static byte mode;
//Some other stuff
};
byte Voice::mode{}; //Static member defined outside of struct declaration
and
struct DataPacket {
DataPacket() : sequencer{}, voice{}, tempdata{} {};
Sequencer sequencer;
Voice voice[4];
Tempdata tempdata;
};
I want to assign one of the voice struct members in the array with a variable value like this:
DataPacket assignVoiceValues(const InputPacket &inputPacket,
DataPacket &dataPacket,
const byte &voiceNumber) {
dataPacket.voice[voiceNumber].mode = (byte) inputPacket.finalPotvalue[0];
//Other code
}
Even though this compiles, when i test the code all of the four structs members mode in the voice[] array are simultaneously assigned with inputPacket.finalPotvalue[0]. There is no code for assigning values to dataPacket.voice[voiceNumber].mode elsewhere that could possibly interfere.
I have no idea why this is happening. What am i missing, and what is the proper syntax for making it work as intended?
(I know vectors generally are recommended over arrays, but the code is intended for an arduino board with limited memory).
You have define mode as static byte mode;... So there's space allocated for exactly one of them in the entire program.
Perhaps mode should not be marked as static?
Since you declare variable "mode" static it is bound to your class (which is single), not to instances of your class (you can create a lot of instances).
To fix the problem just remove static from description of your variable
https://en.cppreference.com/w/cpp/language/static

How to define a well made message class in C++

At the moment I am working on a message class in C++ for data communication, e.g. over a serial port. For this question let's say I have two different messages (I do have more), e.g. a gyroscope- and a acceleration message both with calibration data and sensor values. Since I am an engineer who learned C++ for himself I had a look at my favorite C++ book and figured out that it might be useful to use a factory pattern for the message.
So a simplified version of my header file looks like this:
#ifndef MESSAGE_H
#define MESSAGE_H
#include <cstddef>
class message
{
public:
/**
* \brief ~message:
* Virtual destructor of the class message.
*/
virtual ~message();
/**
* \brief getMessage:
* Creates a message (with new).
*
* \param[in] size Size of the dataArray.
* \param[in] data Bytearray of the message.
*
* \return If messagetype in the Array data eqal to 0 => new GyroMessage.
* If messagetype in the Array data eqal to 1 => new AccelMessage.
* Else => new NotValidMessage.
*
*/
static message* getMessage(size_t size, char* data);
protected:
/**
* \brief message:
* Default konstructor of the class message.
*
* \param[in] size Size of the dataArray.
* \param[in] data Bytearray of the message.
*
*/
message(size_t size, char* data);
/// Size of the dataArray.
int size;
/// Bytearray of the message.
char* dataArray;
/// Type of message.
char messagetype;
};
#endif // MESSAGE_H
The clases GyroMessage, AccelMessage and NotValidMessage are child classes of message. There are two things I do not like about this pattern:
First: If I want to add a new message, it is now enough to add a new class which is inherited form message, you have to add another if statement is in the static function getMessage.
Second: If I want to use the data e.g. from the GyroMessage, I have to reinterpret_cast the message.
Is there a better pattern that I could use for this purpose?
I'm not sure my ideas are good but it costs nothing sharing.
I've done something similar few days ago for Arduino, and for my case I made this choices:
for me the data payload is a pod (plain old data) struct where the compiler is informed to pack it. To achieve so I used a define that handles the compiler directive to pack it (for g++ is __attribute__((packed)))
the class in my case handles almost everything, thus I written it with a template. The template is for the payload struct
for sending the message in byte array I used a templated union inside the class. You have to check the byte ordering of the sender and receiver if you use this method. Something like that:
template <class P>
union Packet {
P data;
unsigned char buff[sizeof(P)];
}
My toolchain supports template so I used them. But you can use more template to insert more packages inside the same union. You need only to remember to have a common field in all the struct that identifies the kind of package (see below).
my class does not handles reading and writing, but instead requires the user of the class to provide 2 callbacks for reading and writing that accepts as arguments the buffer itself, the dimension of the buffer and a void pointer for user data. I think this is a good way to make the class agnostic with respect to the transmission channel.
The example (I'm simplifying a lot):
template <class A, class B, std::size_t N>
union Packet {
A a;
B b;
unsigned char buffer[N];
};
#define PAYLOAD(X, Y) struct X \
Y __attribute__((packed)); \
typedef struct X X;
template <class A, class B, std::size_t N>
class Message {
union Packet<A, B, N> packet;
// [...]
}
// [...]
// Time to declare you messages
PAYLOAD(GyroMessage, { char type; float x; float y; })
PAYLOAD(AccelMessage, { char type; float x; float y; float z; })
// GyroMessage will always have type = 0x01 and
// AccelMessage will always have type = 0x02 for example
// you know that sizeof(AccelMessage) > sizeof(GyroMessage)
// there is for sure a way to automatize this thing at
// compilation time through macros.
// Time to declare the class
Message<GyroMessage, AccelMessage, sizeof(AccelMessage)> message;
To retrieve the correct value you can still (through the union) access the value that you want, without adding new particular functions. But at the moment I don't have a very nice way to access them programmatically.
Those are only some hints, I really don't know what you are doing or which are your priority. So take them with caution.
A factory function is an excellent solution when you want to work generically, with knowledge of which type to create either inferred or known only at the point of creation.
If you know what type you want to create, and you are planning to use the created class with a pointer to the specific, derived type (using its specific interface) then you do not need a factory function. Create what you need and use it! In that case, you need a base class only for common functionality and/or for passing to specific functions which work on all derived types generically.
Alternatively, if you do want to work generically, then you can use a factory function and not cast the result. Work with a pointer to the base class. Have a common interface and handle the differences internally. If you can not do this, then your scenario is not a candidate for this approach.

msgpage C++ : send raw pointer with MSGPACK_DEFINE

I would like to send the following struct over msgpack.
struct MyStruct {
std::string name{""};
int* val{nullptr};
MSGPACK_DEFINE( name, val );
};
Thus far in all of my projects, the only way I've streamed with msgpack is using MSGPACK_DEFINE, then writing the struct to msgpack::sbuffer (and sending it). the MSGPACK_DEFINE macro complains that that perhaps I missed the "->" so I'm guessing it doesn't detect that it's a pointer.
Smart pointers seem to work though:
struct MyStruct {
std::string name{""};
std::shared_ptr<int> val{nullptr};
MSGPACK_DEFINE( name, val );
};
The caveat is that the receiver on the other end needs val to be a raw pointer. I would like to do this without converting on the receiving side. Any ideas?
You failed to explain why you wish to do this. Pointers are never meaningful when serialized (otherwise it is in-process data and there is no need to serialize).
Just pass the value that the pointer points to. If you need to represent "a number or NULL", then pass a struct containing an integer and boolean.
struct NullableInt {
int value{0};
bool null{true};
};

Best practices to implement a Payload-containing class in C++?

I have a question about hierarchy, references and pointers... The question comes to my mind when I had tried to do the following stuff:
class packet {
public:
int address;
int command; /**< Command select the type of Payload that I must decode */
Payload p; /**< Generic payload, first question:
Payload p or Payload * p or Payload &p ?
I have a background in C, for this reason I prefer
Payload p but I know that this is not recommended for C++ */
private:
/** All getter and setter for attributes */
/** Second question: What is the best way to implement a getter
and setter for Payload?... I prefer something
similar to Java if this is possible */
}
Now imagine that I have a lot of types of Payload, all these payloads are children of the super class (generic) Payload.
I want to read the header and switch o the command. For example, if command is 1 I create a PayloadReset : Payload and fill in all of its attributes, then I want to set on my packet this payload (up-casting). In other part of the program I want to read my current packet and then read the command field and down-cast to the appropriate type depending on the command field.
When I tried to do this, I could do the up-casting without problems but the problem comes when I tried to do the downcasting to the specific Payload, in our example PayloadReset.
To answer the first question (which was buried inside the comments in your first code example:
Payload *p;
The first thing you need to learn as part of your transition from Java to C++ is what pointers are and how they work. What will be confusing to you, for some time, is the fact that all objects in Java are really pointers. You never needed to know that, when working with Java. But you must know that now, in order to understand C++. So, declaring a C++ class as
Payload p;
Is not the same thing as making a similar declaration in Java. There is no equivalent to this declaration in Java. In Java you really have a pointer here, and you have to instantiate it using the new keyword. That part Java originally aped from C++. This is the same process as C++, except that you have to explicitly declare it as a pointer.
Payload *p;
Then, somewhere else, using your example of a PayloadReset subclass:
class PayloadReset : public Payload { /* Class declaration */ };
PayloadReset *r = new PayloadReset( /* Constructor argument */ };
p=r;
And the second thing you need to learn as part of your transaction from Java to C++ is when, and how, to delete all instantiated objects. You don't have Java's garbage collector here. This becomes your job, now.
Tagging onto Sam's answer.
Before you go any further, learn the difference between stack and heap allocation. In the example you posted, you're allocating your Payload p; object on the stack - implying that the size of the object is known at this point and said size will be allocated on the stack. If you wanted to assign an derived object to p, it wouldn't work, because said object will likely be of different size. This is why you instead declare a pointer to the object (8 bytes on 64-bit architecture, 4 bytes on 32 bit), and then when you know which type of derived object you want to allocate, you do it using the new operator, as such:
Payload *p;
p = new PayloadReset(...);
The above method would require manually managing memory, i.e. calling delete on the new allocated pointer. As of C++11, the recommendation is to use smart pointers from the <memory> header. These are essentially reference counted pointers that automatically call delete for you.
std::shared_ptr<Payload> p;
p = std::make_shared<PayloadReset>(...);
Your question is somewhat related to Java syntax, but mostly about Object Oriented Programming.
First of all, you should take a moment to get familiar with Java naming conventions. There are commonly used recommendations that you can find all over the web. Here is one example of Java Naming Conventions. I brought this up because single variable names is generally not a good idea and having descriptive variables names pays dividends as the program grows in size and especially if there are more than one person on a team. So, instead of Payload p use Payload payload.
Secondly, in OO (Object Oriented), it is best to always keep your Class instance variables private, not public. Give access to these variables only if necessary and shield access to them by providing public methods. So, in your example of class Packet, your public/private is backwards. Your class should look more like:
public class Packet{
//private fields
private int address;
private int command;
private Payload payload;
//Maybe provide a nice constructor to take in expected
//properties on instantiation
public Packet(Payload pay){
}
//public methods - as needed
public void getPayload(){
return this.payload;
}
public void setAddress(int addy){
this.address = addy;
}
public int getCommand(){
return this.command;
}
}
Also, to answer more of your question about the naming of Payload. Like i said earlier..use descriptive names. Java does not have pointer references like C and generally handles memory management for you, so the & is not required or supported.
Your last question/topic is really again about OO and Class heirarchy.
It seems that Payload would be a generic base class and you may have multiple, specific 'Payload types', like ResetPayload. If that is the case, you would then define Payload and create the ResetPayload class that extends Payload. I'm not sure exactly what you are trying to do, but think of Classes/objects ad nouns and methods as verbs. Also think about the 'is-a' and 'has-a' concept. From what I see, maybe all Payloads 'has-acommand and an address. Also, maybe eachPayloadalso has multiplePackets, whatever. Just as an example, you would then define yourPayload` class like this:
public class Payload{
private int address;
private int command;
private List<Packet> packets = new ArrayList<>();
public Payload(int addy, int comm){
this.address = addy;
this.command = comm;
}
public void addPacket(Packet p){
packets.add(p);
}
public List<Packet> getPackets(){
return this.packets;
}
public int getCommand(){
return this.command;
}
public int getAddress(){
return this.address;
}
}
Then if you had a type of Payload that is more specific, like Reset, you would create the class, extends Payload and provide the additional properties/operations specific to this type, something this like:
public class ResetPayload extends Payload{
public ResetPayload(int addy, int comm){
super(addy, comm);
}
public void reset(){
//Do stuff here to reset the payload
}
}
Hopefully, that answers your questions and moves you along further. Good luck.
Here is my take on the general problem, it extends the tagged union idea. Advantages are 1.) no inheritance/dynamic_cast 2.) no shared ptr 3.) POD 4.) rtti is used to generate unique tags:
using cleanup_fun_t = void(*)(msg*);
class msg
{
public:
template<typename T, typename... Args>
static msg make(Args&&... args);
private:
std::type_index tag_;
mutable std::atomic<cleanup_fun_t> del_fn_; // hell is waiting for me,
uint64_t meta_;
uint64_t data_;
};
Please fill in all the nice member functions. This class is move only. You are creating messages with payload by the static member function make:
template<typename T, typename... Args>
msg msg::make(Args&&... args)
{
msg m;
m.tag_ = typeid(T);
m.del_fn_ = nullptr;
if (!(std::is_empty<T>::value))
{
auto ptr = std::make_unique<T>(std::forward<Args>(args)...);
m.data_ = (uint64_t)ptr.release();
m.del_fn_ = &details::cleanup_t<T>::fun; // deleter template not shown
}
return m;
}
// creation:
msg m = msg::make<Payload>(params passed to payload constructor);
// using
if (m.tag() == typeid(Payload))
{
Payload* ptr = (Payload*)m.data;
ptr-> ...
}
Just check the tag if it contains your expected data (type) and cast the data to a pointer type.
Disclaimer: It is not the complete class. Some access member function are missing here.

C++/Pointer to a Structure/ validate members

below is my structure which i expose to user to populate it by giving it some size using malloc.
the use passes me the pointer to this structure
typedef struct ServerConfiguration {
wchar_t *IPAddress;
USHORT PortNo;
wchar_t *Title;
int repeatCount;
int timeout;
} ServerConfig;
ServerConfig *serverconfig = (ServerConfig*)malloc(sizeof(ServerConfig));
dcmServerconfig->IPAddress = L"localhost";
dcmServerconfig->Title = L"DVTK_MW_SCP";
dcmServerconfig->PortNo = 8080;
user doe not assign repeat count//
which points to some junk address loc //example repeatCount=380090700
i have another structure which has struct,
typedef struct CommonParameters {
//other members;
int repeatCount
} commonParams;
i have to validate ServerCOnfig values and then assign it to CommonParameters as show below
if (serverConfig->opt_repeatCount > 1) {
commonParams.repeatCount = serverConfig->repeatCount;
}
The value of serverConfig->repeatCount is some junk(380090700) if not assigned by user. and which is greater than 1 in my case. I need to validate if this serverConfig->repeatCount is having a valid value then only pass the if condition
Ultimately my question is to validate a structure variable which is integer for a proper value.
Your code looks like it's written in a very C-based style (i.e. allocating a chunk of memory with malloc and then initializing the struct's fields manually). If you adopt a more common C++-based style where you use new to allocate your memory and constructors to initialize your fields you'll find these kinds of problems become easier. For example, in your case you could write CommonParameters as:
struct CommonParameters {
CommonParameters(int rc) :
repeatCount(rc)
{}
//other members;
int repeatCount
};
This way CommonParameters is initialized when it's created and you don't have to worry about its initialization status.
NOTE: Because your question is written in what looks like pure C you may have just mis-tagged the question as C++. If so, please change the tag and I'll update my answer.