In Win CE 6.0, class TankObject is defined in a static library, C++ compiler is VS2008; target is ARM4 (/QRarch4).
An instance of class TankObject is constructed by a call of the form
*TankObject myTankObject = new TankObject(parm1, parm2 ...);
Last attribute declared in TankObject definition is an object pointer, and when an assignment is made to same, memory corruption of another dynamically allocated object occurs.
Step into constructor reveals that operator new is called with a size of 0x500. sizeof(TankObject) reveals two different values, depending on the context:
In instantiating context (the application), sizeof(TankObject) and sizeof(*myTankObject) is 0x500.
In context of the object itself (the constructor, or object methods), sizeof(TankObject) and sizeof(*this) is 0x508. The address of last declared attribute is 0x500, relative to object.
The call to new requests and receives 0x500 bytes. The object itself expects and uses 0x508 bytes, which can cause assignments to last attribute to step on other dynamically allocated objects.
Work around is to declare another unused attribute at the end of the object definition, to pad the request to new.
Both contexts include the same .h file, to debug I changed include statement to an explicit path name. I also went through compiler switches, made them identical. So I am puzzled, if any one can shed light, I'm glad, I would like to know a proper solution.
Related
Demo demo=new Demo();
Here demo is a reference variable. Are reference variables equal to object references... ?
If no then please explain the concept of object reference.
Demo represents the type of the object.
demo represents the object reference, you will be able to refer to new Demo() object and calling its methods (for example).
new Demo() represents the object itself which is situated in heap memory.
In case of java language,
When you write the statement
Demo obj = new Demo();
It means that You are declaring a variable named obj and it is of type Demo.
by writing
obj = new Demo();
You are creating a new object in the heap memory and the reference variable "obj" will refer to it so that when you want to access the object created just now, you can access it through reference variable "obj".
so when you want to call some method on Demo object, you can call it using
obj.someMethod();
A reference to an object is a way to denote that object. The address of an object, for example, is one kind of reference (probably the simplest kind). Other kinds of references can exist, too, and they are written and read using some more complicated logic. It could theoretically be a double pointer, a pseudo-address, or something else - as long as it contains enough information that (if interpreted in a specified way) can be used to denote a specific object, .
A reference variable is a variable whose value is a reference to an object. So, for example, a reference variable could be a variable whose value is the address of an object, or (as I described above) something different, but equivalent.
For comparison, the other common type of variable (called primitive type in Java, value type in C# and other names in other contexts) is the kind variable whose value is an actual object (instead of a reference).
I am trying to save an Object which implements an Interface say IInterface.
private PersistentDictionary<string, IInterface> Object = new PersistentDictionary<string, IInterface>(Environment.CurrentDirectory + #"\Object");
Since many classes implement the same interface(all of which need to cached), for a generic approach I want to store an Object of type IInterface in the dictionary.
So that anywhere I can pull out that object type cast it as IInterface and use that object's internal implementation of methods etc..
But, as soon as the Esent cache is initialized it throws this error:
Not supported for SetColumn
Parameter name: TColumn
Actual value was IInterface.
I have tried to not use XmlSerializer to do the same but is unable to deserialize an Interface type.Also, [Serializable] attribute cannot be used on top of a Interface, so I am stuck.
I have also tried to make all the implementations(classes) of the Interface as [Serializable] as a dying attempt but to no use.
Does any one know a way out ? Thanks in advance !!!
The only reason that only structs are supported (as well as some basic immutable classes such as string) is that the PersistentDictionary is meant to be a drop-in replacement for Dictionary, SortedDictionary and other similar classes.
Suppose I have the following code:
class MyClass
{
int val;
}
.
.
.
var dict = new Dictionary<int,MyClass>();
var x = new MyClass();
x.val = 1;
dict.Add(0,x);
x.val = 2;
var y = dict[0];
Console.WriteLine(y.val);
The output in this case would be 2. But if I'd used the PersistentDictionary instead of the regular one, the output would be 1. The class was created with value 1, and then changed after it was added to the dictionary. Since a class is a reference type, when we retrieve the item from the dictionary, we will also have the changed data.
Since the PersistentDictionary writes the data to disk, it cannot really handle reference types this way. Serializing it, and writing it to disk is essentially the same as treating the object as a value type (an entire copy is made).
Because it's intended to be used instead of the standard dictionaries, and the fact that it cannot handle reference types with complete transparency, the developers instead opted to support only structs, because structs are value types already.
However, if you're aware of this limitation and promise to be careful not to fall into this trap, you can allow it to serialize classes quite easily. Just download the source code and compile your own version of the EsentCollections library. The only change you need to make to it is to change this line:
if (!(type.IsValueType && type.IsSerializable))
to this:
if (!type.IsSerializable)
This will allow classes to be written to the PersistentDictionary as well, provided that it's Serializable, and its members are Serializable as well. A huge benefit is that it will also allow you to store arrays in there this way. All you have to keep in mind is that it's not a real dictionary, therefore when you write an object to it, it will store a copy of the object. Therefore, updating any of your object's members after adding them to the PersistentDictionary will not update the copy in the dictionary automatically as well, you'd need to remember to update it manually.
PersistentDictionary can only store value-structs and a very limited subset of classes (string, Uri, IPAddress). Take a look at ColumnConverter.cs, at private static bool IsSerializable(Type type) for the full restrictions. You'd be hitting the typeinfo.IsValueType() restriction.
By the way, you can also try posting questions about PersistentDictionary at http://managedesent.codeplex.com/discussions .
-martin
I am making a simple debugger window in ActionScript for myself where I can add and remove variables I want to track. I was to be able to add variables to the list by just doing something like
DebuggerMonitor.trackVar(variable).
My question is, is there any way I can turn "variable" itself (the name, not the value) into a String to be added into a text field?
Depending on how "intelligent" your debugger should be, you could just pass the name along:
DebuggerMonitor.trackVar( variable, "variable" );
since obviously, when used in a context like this, the name should be known at the time you are writing the program.
You can also do some reflection magic to get instance variable names, but it won't work for temp variables (their names are dropped at compilation time):
public function getVariableName( instance:*, match:* ):String {
var typeDescription:XML = describeType( instance );
var variables:XMLList = typeDescription..variable;
var accessors:XMLList = typeDescription..accessor;
for each(var variable:XML in variables)
if(matchesXMLName( instance, variable, match ))
return variable.#name;
for each(var accessor:XML in accessors)
if(matchesXMLName( instance, accessor, match ))
return accessor.#name;
return "No name found.";
}
private function matchesXMLName( instance:*, xml:XML, match:* ):Boolean {
return match == instance[xml.#name.toString()];
}
var varName:String = getVariableName ( myObject, variable );
Using reflections like this will also be quite costly, if used often - you will have to think of a way to cache the type descriptions.
I recommend you check out the as3commons reflections package - there is a lot of useful functionality in there...
Short answer - No :(
You can access the type name but not individual instance names, as these are lost at run-time.
There is a confusion caused by the keyword 'var' because it is used to create several types of bindings.
Lexical bindings (the keyword 'var' was used inside a function).
Dynamic bindings (the keyword 'var' was used to declare a class' field).
Lexical bindings are interpreted by the compiler at compile time as addresses of the registers of the registers space occupied by the function. The names given to lexical bindings perish at this time and it is not possible to restore them at runtime - therefore you can't get the "name" of the variable.
Dynamic bindings are a kind of "public API" of the objects that declare them, they may be accessed from the code that was not compiled together with the code that created them, this is why, for the purpose of reflection the names of these bindings are stored in compiled code. However, ActionScript has no way of referencing LHS values, so you cannot, even if you know the name of the variable and the object declaring it, pass it to another function. But you can look it up in the debugger or by calling describeType on the object declaring the variable. Note that describeType will not show information on private variables even if you are calling it from the scope of the object in question.
I am working with the classes in the System.Windows.Documents namespace, trying to write some generic code that will conditionally set the value of certain dependency properties, depending on whether these properties exist on a given class.
For example, the following method assigns an arbitrary value to the Padding property of the passed FrameworkContentElement:
void SetElementPadding(FrameworkContentElement element)
{
element.SetValue(Block.PaddingProperty, new Thickness(155d));
}
However, not all concrete implementations of FrameworkContentElement have a Padding property (Paragraph does but Span does not) so I would expect the property assignment to succeed for types that implement this property and to be silently ignored for types that do not.
But it seems that the above property assignment succeeds for instances of all derivatives of FrameworkContentElement, regardless of whether they implement the Padding property. I make this assumption because I have always been able to read back the assigned value.
I assume there is some flaw in the way I am assigning property values. What should I do to ensure that a given dependency property assignment is ignored by classes that do not implement that property?
Many thanks for your advice.
Tim
All classes that derive from Block have the Padding property. You may use the following modification:
void SetElementPadding(FrameworkContentElement element)
{
var block = element as Block;
if (block == null) return;
block.Padding = new Thickness(155d);
}
Even without this modification everything would still work for you because all you want is for Padding to be ignored by classes that do not support it. This is exactly what would happen. The fact that you can read out the value of a Padding dependency property on an instance that does not support it is probably by design but you shouldn't care. Block and derivatives would honor the value and all others would ignore it.
ATL provides a bunch of macros for creating so-called COM maps - chains of rules of how the QueryInterface() call behaves on a given object. The map begins with BEGIN_COM_MAP and ends with END_COM_MAP. In between the the following can be used (among others):
COM_INTERFACE_ENTRY, COM_INTERFACE_ENTRY2 - to ask C++ to simply cast this class to the corresponding COM interface
COM_INTERFACE_ENTRY_FUNC - to ask C++ to call a function that will retrieve the interface
Now the problem is I want to use COM_INTERFACE_ENTRY_FUNC for every interface I expose so that I can log all the calls - I believe it will help me debugging my component when it is deployed in the field. The implementation of CComObjectRootBase::InternalQueryInterface contains an ATLASSERT:
ATLASSERT(pEntries->pFunc == _ATL_SIMPLEMAPENTRY);
which implies that the following is allright:
BEGIN_COM_MAP
COM_INTERFACE_ENTRY( IMyInterface1 )
COM_INTERFACE_ENTRY_FUNC( __uuidof(IMyInterface2), 0, OnQueryMyInterface2 )
END_COM_MAP
since here the first entry results in _ATL_SIMPLEMAPENTRY type entry but the following is not:
BEGIN_COM_MAP
COM_INTERFACE_ENTRY_FUNC( __uuidof(IMyInterface1), 0, OnQueryMyInterface1 )
COM_INTERFACE_ENTRY_FUNC( __uuidof(IMyInterface2), 0, OnQueryMyInterface2 )
END_COM_MAP
since here the entry type will not be _ATL_SIMPLEMAPENTRY.
This makes no sense at all. Why am I enforced into having a "please, C++, do the static_cast" entry as the first entry of the COM map?
Upd: Resolved after many more hour of debugging, answer added.
Inside ATL there's AtlInternalQueryInterface() that actually does scan the COM map. Inside it there's this code:
if (InlineIsEqualUnknown(iid)) // use first interface
{
IUnknown* pUnk = (IUnknown*)((INT_PTR)pThis+pEntries->dw);
// call AddRef on pUnk, copy it to ppvObject, return S_OK
}
this code actually relies on the first entry of the table being of _ATL_SIMPLEMAPENTRY type since it expects that _ATL_INTMAP_ENTRY::dw stores an offset from the current object this pointer to the necessary interface. In the use cited in the question if the first entry is this one:
COM_INTERFACE_ENTRY_FUNC( __uuidof(IMyInterface1), 0, OnQueryMyInterface1 )
the entry will be of wrong type, but the _ATL_INTMAP_ENTRY::dw will be zero (second parameter to the macro) and the code will happily work each time returning this pointer as IUnknown*. But if the second macro parameter which corresponds to a pass this value into the function specified as the third parameter variable is not zero the program will use that value as the offset and could run into undefined behaviour.