Difference between "struct" and "value struct" - c++-cli

What is the difference between
public struct X{
public:
int A;};
and
public value struct X{
public:
int A;};
How can I convert one into the other?

The first is a normal C++ structure.
Using value struct creates a C++/CLI value type (a .NET structure). You typically will want to copy from one to the other manually, though if the memory layout is the same, you can often use things like Marshal::PtrToStructure to copy the data directly. Note that this returns a boxed value struct, however, so manual copying is often more efficient.

Related

Can I have a string object store its data within the structure?

I'm looking for a quick way to serialize custom structures consisting of basic value types and strings.
Using C++CLI to pin the pointer of the structure instance and destination array and then memcpy the data over is working quite well for all the value types. However, if I include any reference types such as string then all I get is the reference address.
Expected as much since otherwise it would be impossible for the structure to have a fixed.. structure. I figured that maybe, if I make the string fixed size, it might place it inside the structure though. Adding < VBFixedString(256) > to the string declaration did not achieve that.
Is there anything else that would place the actual data inside the structure?
Pinning a managed object and memcpy-ing the content will never give you what you want. Any managed object, be it String, a character array, or anything else will show up as a reference, and you'll just get a memory location.
If I read between the lines, it sounds like you need to call some C or C++ (not C++/CLI) code, and pass it a C struct that looks similar to this:
struct UnmanagedFoo
{
int a_number;
char a_string[256];
};
If that's the case, then I'd solve this by setting up the automatic marshaling to handle this for you. Here's how you'd define that struct so that it marshals properly. (I'm using C# syntax here, but it should be an easy conversion to VB.net syntax.)
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct ManagedFoo
{
public int a_number;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
public string a_string;
}
Explanation:
StructLayout(LayoutKind.Sequential) specifies that the fields should be in the declared order. The default LayoutKind, Auto, allows the fields to be re-ordered if the compiler wants.
CharSet=CharSet.Ansi specifies the type of strings to marshal. You can specify CharSet.Ansi to get char strings on the C++ side, or CharSet.Unicode to get wchar_t strings in C++.
MarshalAs(UnmanagedType.ByValTStr) specifies a string inline to the struct, which is what you were asking about. There are several other string types, with different semantics, see the UnmanagedType page on MSDN for descriptions.
SizeConst=256 specifies the size of the character array. Note that this specifies the number of characters (or when doing arrays, number of array elements), not the number of bytes.
Now, these marshal attributes are an instruction to the built-in marshaler in .Net, which you can call directly from your VB.Net code. To use it, call Marshal.StructureToPtr to go from the .Net object to unmanaged memory, and Marshal.PtrToStructure to go from unmanaged memory to a .Net object. MSDN has some good examples of calling those two methods, take a look at the linked pages.
Wait, what about C++/CLI? Yes, you could use C++/CLI to marshal from the .Net object to a C struct. If your structs get too complex to represent with the MarshalAs attribute, it's highly appropriate to do that. In that case, here's what you do: Declare your .Net struct like I listed above, without the MarshalAs or StructLayout. Also declare the C struct, plain and ordinary, also as listed above. When you need to switch from one to the other, copy things field by field, not a big memcpy. Yes, all the fields that are basic types (integers, doubles, etc.) will be a repetitive output.a_number = input.a_number, but that's the proper way to do it.

C++ CLI error C2228

I'm working on a C++/Cli project, so I defined my struct like this.
ref struct token_t
{
public :
static TokenTypes_t TokenType; ///enum class
static String ^ TokenString; ///enum class
static Keyword_t KeywordID; ///enum class
static int IntVal;
static char CharVal;
static Operator_t OprID; ///enum class
};
I passed an instance of this struct as a function parameter, but when I tried to do something like : token.TokenString.pop_back(); it says :
Error 11 error C2228: left of '.pop_back' must have class/struct/union
Did you declare the struct statics somewhere? From your code it is not apparent if you did that or not. If you did not, then mere struct instantiation would NOT get you static member instantiation. You need to instantiate the static members somewhere. Something like
struct token_t::TokenString = "foo"; (correct the syntax if wrong)
First, a System::String (the String^ you declared) doesn't have a pop_back method. Look it up on MSDN for more info.
Second, you declared it static. You are trying to use it with an instance. That doesn't match. Most likely, you don't want any of that static stuff. Remove it.
You also need to access methods of a XXX^ type with the -> operator as if it were a normal pointer.
You need to use the arrow access operator. Other then that, you seem to use System.String as if it was std::string from the native C++ standard library...
OK, several things:
String^ is a reference type, you need to use -> rather than . when calling methods on it.
There is no method pop_back on the string class.
TokenString is declared static, therefore the proper way to access it is token_t::TokenString. If it's static, it's not associated with a particular instance of the type, only with the type itself.
You've got the type declared as ref struct. This is perfectly valid, but confusing. The ref wins out over the struct, so what you have is the same as ref class. If you want a struct (i.e., a value type, not a reference type), you should say value struct token_t. (value class will give you the same result as value struct, but that's again confusing.)
The proper members of the String class are SubString, and Length. Therefore, the line to remove the last character from the string would be this: token_t::TokenString = token_t::TokenString->SubString(0, token_t::TokenString->Length - 1);

Where is the definition of a class stored in memory as opposed to the instance?

This question is merely out of interest and trying to understand something about memory management in object-oriented languages. It is not specific to one language, but I just want to understand as a general principle.
What I want to know is how the definition of an object reference is stored compared to the instance of that reference.
When you define and object in OO source code, e.g. in Java, without instantiating it:
String s;
How does this get stored? How does the memory usage of this definition differ from when the object is actually instantiated:
s = new String("abc");
? Is there a general principle that applies to all OO languages in terms of how memory is allocated or do different language implementers use different techniques for allocating memory?
Normaly when we declare a refrence like String s; it is created as a normal variable just like int , float but this type of variable hold the memory address ( it similar concept as pointers in C language) but when we use s = new String("abc");, it creates an object in heap and assign that address to the reference variable s.
In Java byte code, all Objects are stored as Objects. Explicit type-checking is added when needed. So for example this Java function
public Integer getValue(Object number){
int i = ((Number) number).toInt();
return new Integer(i);
}
is translated to a bytecode like this:
(accepts java.lang.Object, returns java.lang.Integer)
-read the first argument as an Object
-if the value is not a Number, raise an exception
-call the virtual method toInt(java.lang.Integer) of the value
and remember the int result
-use the value as an int argument
-instantiate a new java.lang.Integer
-call the constructor(int) of java.lang.Integer on the new number,
getting an Object back
[since the declared return value of Number.toInt is the same
as the return value of our function, no type checking is needed]
-return the value
So, types of unused variables get stripped out by the compiler. Types of public and protected fields are stored with its class.
The runtime type of an Object is stored with the object. In C++, it is a pointer to the Virtual Method Table. In Java, it is as a 16-bit index into the table of all loaded classes.
The Java class file stores an index of all dependent classes in a similar table. Only the class names are stored here. All field descriptions then point to this table.
So, when you write String s = new String("abc") (or even String s = "abc"), your class stores:
it is dependent on the class java.lang.String in the table of dependencies
"abc" in the table of String literals
your method loading a String literal by ID
(in the first case) your method calling a constructor of its first dependent class (String) with the first dependent class (String) as an argument.
the compiler can prove storing the new String in a String variable is safe, so it skips the type checking.
A class can be loaded as soon as it is referenced, or as late as its first use (in which case it is refered to by its depending class and ID within the class). I think the latter is always the case nowadays.
When a class is loaded:
-its class loader is asked to retreive the class by its name.
-(in the case of the system loader) the class loader looks
for the corresponding file in the program JAR, in the system library
and in all libraries referenced.
-the byte stream is then decoded into a structure in memory
-(in the case of early loading) all dependent classes are loaded recursively
if not already loaded
-it is stored in the class table
-(in the case of late loading) its static initialiser is run
(possibly loading more classes in the process).
In C++, none of the class loading takes place, as all user classes and most libraries are stored in the program as a mere virtual method table and the corresponding method. All of the system functions (not classes) can still be stored in a DLL (in case of Windows) or a similar file and loaded by the library at runtime. If a type checking is implied by an explicit type-cast, it is performed on the virtual method table. Also note that C++ did not have a type checking mechanism for a while.

boost::serialization polymorphic type initialization

I have a base class and 4 derived classes. I store all my derived classes in a vector of base class pointer type. During first initialization I create each derived type differently using their constructors. Basically they each have different param types in their ctors. (I had to provide a protected default ctor to make BOOST_CLASS_EXPORT compile but that's a different story). I don't/can't save all the members (filled in ctor) of these derived classes.
Now, when I load objects from the disk using boost::serialize, these members (that are not serialized and specific to each derived type) are destroyed. And, I cannot think of a way to re-initialize these derived types since I only store the base class pointers.
What exactly I need is being able to load my derived types (pointers) partially, without deleting all their content..
Is there a way to overcome this, a magic boost define or function call perhaps? Otherwise, polymorphism with boost::serialize is not possible at all.. I should be missing something and hope I could define my problem good enough.
You shouldn't need to create a default constructor just for serialization. You can instead have boost save/load the data needed by a non-default constructor, and use that to construct new objects when loading.
That way, whatever your constructors do to ensure the validity of data members can also happen during serialization, and the serialization library never has to manipulate the data members of your objects directly. This should prevent data erasure.
For example, if your class can be constructed using a name and a size, you could overload the functions as follows:
template <class Archive>
inline void save_construct_data(Archive & ar, const my_class * t, const unsigned int) {
ar << my_class->name();
ar << my_class->size();
}
template<class Archive>
inline void load_construct_data(Archive & ar, my_class * t, const unsigned int) {
std::string name;
int size;
ar >> name;
ar >> size;
::new(t)my_class(name, size); // placement 'new' using your regular constructor
}
Check out the docs here.

Object Slicing, Is it advantage?

Object slicing is some thing that object looses some of its attributes or functions when a child class is assigned to base class.
Some thing like
Class A{
}
Class B extends A{
}
Class SomeClass{
A a = new A();
B b = new B();
// Some where if might happen like this */
a = b; (Object slicing happens)
}
Do we say Object slicing is any beneficial in any ways?
If yes, can any one please tell me how object slicing be a helpful in development and where it might be helpful?
In C++, you should think of an object slice as a conversion from the derived type to the base type[*]. A brand new object is created, which is "inspired by a true story".
Sometimes this is something that you would want to do, but the result is not in any sense the same object as the original. When object slicing goes wrong is when people aren't paying attention, and think it is the same object or a copy of it.
It's normally not beneficial. In fact it's normally done accidentally when someone passes by value when they meant to pass by reference.
It's quite hard to come up with an example of when slicing is definitively the right thing to do, because it's quite hard (especially in C++) to come up with an example where a non-abstract base class is definitively the right thing to do. This is an important design point, and not one to pass over lightly - if you find yourself slicing an object, either deliberately or accidentally, quite likely your object hierarchy is wrong to start with. Either the base class shouldn't be used as a base class, or else it should have at least one pure virtual function and hence not be sliceable or passable by value.
So, any example I gave where an object is converted to an object of its base class, would rightly provoke the objection, "hang on a minute, what are you doing inheriting from a concrete class in the first place?". If slicing is accidental then it's probably a bug, and if it's deliberate then it's probably "code smell".
But the answer might be "yes, OK, this shouldn't really be how things are structured, but given that they are structured that way, I need to convert from the derived class to the base class, and that by definition is a slice". In that spirit, here's an example:
struct Soldier {
string name;
string rank;
string serialNumber;
};
struct ActiveSoldier : Soldier {
string currentUnit;
ActiveSoldier *commandingOfficer; // the design errors multiply!
int yearsService;
};
template <typename InputIterator>
void takePrisoners(InputIterator first, InputIterator last) {
while (first != last) {
Soldier s(*first);
// do some stuff with name, rank and serialNumber
++first;
}
}
Now, the requirement of the takePrisoners function template is that its parameter be an iterator for a type convertible to Soldier. It doesn't have to be a derived class, and we don't directly access the members "name", etc, so takePrisoners has tried to offer the easiest possible interface to implement given the restrictions (a) should work with Soldier, and (b) should be possible to write other types that it also works with.
ActiveSoldier is one such other type. For reasons best known only to the author of that class, it has opted to publicly inherit from Soldier rather than providing an overloaded conversion operator. We can argue whether that's ever a good idea, but let's suppose we're stuck with it. Because it's a derived class, it is convertible to Soldier. That conversion is called a slice. Hence, if we call takePrisoners passing in the begin() and end() iterators for a vector of ActiveSoldiers, then we will slice them.
You could probably come up with similar examples for an OutputIterator, where the recipient only cares about the base class part of the objects being delivered, and so allows them to be sliced as they're written to the iterator.
The reason it's "code smell" is that we should consider (a) rewriting ActiveSoldier, and (b) changing Soldier so that it can be accessed using functions instead of member access, so that we can abstract that set of functions as an interface that other types can implement independently, so that takePrisoners doesn't have to convert to Soldier. Either of those would remove the need for a slice, and would have potential benefits for the ease with which our code can be extended in future.
[*] because it is one. The last two lines below are doing the same thing:
struct A {
int value;
A(int v) : value(v) {}
};
struct B : A {
int quantity;
B(int v, int q) : A(v), quantity(q) {}
};
int main() {
int i = 12; // an integer
B b(12, 3); // an instance of B
A a1 = b; // (1) convert B to A, also known as "slicing"
A a2 = i; // (2) convert int to A, not known as "slicing"
}
The only difference is that (1) calls A's copy constructor (that the compiler provides even though the code doesn't), whereas (2) calls A's int constructor.
As someone else said, Java doesn't do object slicing. If the code you provide were turned into Java, then no kind of object slicing would happen. Java variables are references, not objects, so the postcondition of a = b is just that the variable "a" refers to the same object as the variable "b" - changes via one reference can be seen via the other reference, and so on. They just refer to it by a different type, which is part of polymorphism. A typical analogy for this is that I might think of a person as "my brother"[**], and someone else might think of the same person as "my vicar". Same object, different interface.
You can get the Java-like effect in C++ using pointers or references:
B b(24,7);
A *a3 = &b; // No slicing - a3 is a pointer to the object b
A &a4 = b; // No slicing - a4 is a reference to (pseudonym for) the object b
[**] In point of fact, my brother is not a vicar.