How does InvokeMember know about the HighPart property? - reflection

I want to use the System.Reflection library and not ActiveDs. I found this code on the web that parses the LargeInteger into HighPart and LowPart.
I don't understand it completely, particularly where is the method 'HighPart' and 'LowPart' defined? Is that within the Object class or do I have to define it?
Below is the code that parses the largeInteger:
de = new DirectoryEntry(curDomain,adUser,adPwd);
object largeInteger = de.Properties["maxPwdAge"].Value;
System.Type type = largeInteger.GetType();
int high = (int)type.InvokeMember("HighPart", BindingFlags.GetProperty, null, largeInteger, null);
int low = (int)type.InvokeMember("LowPart", BindingFlags.GetProperty, null, largeInteger, null);
Thanks!

It's defined in the IADsLargeInteger, which is a COM interface.
http://msdn.microsoft.com/en-us/library/aa706037%28v=vs.85%29.aspx
To get rid of ActiveDs, you may defined the type yourself (C#):
[
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
Guid("9068270B-0939-11D1-8BE1-00C04FD8D503")
]
public interface IADsLargeInteger
{
int HighPart{get;set;}
int LowPart{get;set;}
}
private long? GetLargeInt(DirectoryEntry de, string attrName)
{
long? ret = null;
IADsLargeInteger largeInt = de.Properties[attrName].Value as IADsLargeInteger;
if (largeInt != null)
{
ret = (long)largeInt.HighPart << 32 | largeInt.LowPart;
}
return ret;
}

Related

Passing value by reference to Qore script function from C++ code

I need pass returnValue to a method as argument passed by reference and adjust original var value when function id done. So using ReferenceArgumentHelper class.
What's wrong in code bellow when returnValue is unintentionally deleted (when it is a node, i.e. string) and valgrind detects it. callMethod("onFunctionExit" calls an Qore script method and I can see there correct returnValue value. I suspect it's deleted when exiting onFunctionExit when ReferenceArgumentHelper is destroyed. rah.getArg() references reference variable, so it should not be deleted in callMethod.
DLLLOCAL ThreadDebugEnum callMethod(const char* name, const ThreadDebugEnum defaultResult, QoreProgram *pgm, int paramCount, AbstractQoreNode** params, ExceptionSink* xsink) {
int rv;
QoreListNode* l = new QoreListNode();
qore_program_to_object_map_t::iterator i = qore_program_to_object_map.find(pgm);
if (i == qore_program_to_object_map.end()) {
return defaultResult;
}
i->second->ref();
l->push(i->second);
for (int i=0; i<paramCount; i++) {
if (params[i])
params[i]->ref();
l->push(params[i]);
}
rv = qo->intEvalMethod(name, l, xsink);
l->deref(xsink);
return (ThreadDebugEnum) rv;
}
DLLLOCAL virtual ThreadDebugEnum onFunctionExit(QoreProgram *pgm, const StatementBlock *blockStatement, QoreValue& returnValue, ExceptionSink* xsink) {
AbstractQoreNode* params[2];
params[0] = getLocation(blockStatement);
ReferenceArgumentHelper rah(returnValue.takeNode(), xsink); // grab node from returnValue and pass to helper
params[1] = rah.getArg(); // caller owns ref
ThreadDebugEnum rv = callMethod("onFunctionExit", DBG_SB_RUN, pgm, 2, params, xsink);
AbstractQoreNode* rc = rah.getOutputValue(); // caller owns ref
returnValue.assign(rc); // takes reference
// returnValue.ref();
}
return rv;
}
When looking deeply I did not get why compiler is happy with code in /lib/ReferenceArgumentHelper.cpp:
struct lvih_intern {
LocalVar lv;
ExceptionSink* xsink;
ReferenceNode* ref;
DLLLOCAL lvih_intern(AbstractQoreNode* val, ExceptionSink* xs) : lv("ref_arg_helper", 0), xsink(xs) {
printd(5, "ReferenceArgumentHelper::ReferenceArgumentHelper() instantiating %p (val: %p type: '%s') \n", &lv, val, val ? val->getTypeName() : "n/a");
lv.instantiate(val); <--------------
VarRefNode* vr = new VarRefNode(strdup("ref_arg_helper"), VT_LOCAL);
vr->ref.id = &lv;
ref = new ReferenceNode(vr, 0, vr, 0);
}
class LocalVar {
....
DLLLOCAL void instantiate(QoreValue nval) const {
What is behind conversion AbstractQoreNode* to QoreValue in method call? I did not find an overloaded operator or so. I'm looking what exactly happens with references.
** EDIT **
To make a long story short, ReferenceArgumentHelper was buggy; it hadn't been used in years and was not up to date. The class has been fixed which should fix your issue I hope.
Thank you for pointing this out, and let me know if you have any further problems with this or the fix to the affected code.

Replacing HashMap with TreeMap

I am trying to replace HashMap used in my code to TreeMap as I need to have the keys sorted.
But just replacing the HashMap declaration with TreeMap is running into various ClassCast exception which were not arising before. I am debugging the code but I cannot follow why is it failing? It fails in the treemap.put(key, value); statement.
private static void insertIntoIndexFile(String datatype, String value, String columnName, String tableName,
long offset) {
// TODO Auto-generated method stub
Map<Object, ArrayList<Long>> index = new TreeMap<Object, ArrayList<Long>>();
Map<Object, ArrayList<Long>> result = new TreeMap<Object, ArrayList<Long>>();
try{
String indexTableFileName = SCHEMA+"."+tableName+"."+columnName+".ndx";
File indexTableFileObject = new File(indexTableFileName);
long indexfileLength = indexTableFileObject.length();
RandomAccessFile indexTableFile = new RandomAccessFile(indexTableFileObject, "rw");
boolean isValuePresent = false;
if(indexfileLength>0){
// returns sucessfully
index = getIndexFileEntries(indexTableFileName, datatype);
// checking if the key exists
Set set1 = index.entrySet();
Iterator iterator1 = set1.iterator();
while(iterator1.hasNext()) {
Map.Entry me2 = (Map.Entry)iterator1.next();
Object key = me2.getKey();
ArrayList<Long> temp = new ArrayList<Long>();
if(key.toString().equals(value)){
System.out.println("Comparing the hashmap value to value " + key.toString());
isValuePresent = true;
temp = (ArrayList<Long>) me2.getValue();
long frequency = temp.get(0);
frequency++;
temp.set(0, frequency);
temp.add(offset);
index.put(key, temp);
break;
}
}
if(isValuePresent == false){
System.out.println("The file has values but this key was not found. Here is the updated hashmap");
ArrayList<Long> temp = new ArrayList<Long>();
temp.add(Long.parseLong("01"));
temp.add(offset);
Object key = (Object)value;
index.put(key,temp); // this line throws error
writeMapToIndexFile(tableName, columnName, datatype, index);
}else{
writeMapToIndexFile(tableName,columnName, datatype, index);
}
}catch(Exception e){
e.printStackTrace();
}
}
Here is the stacktrace :
java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.String
at java.lang.String.compareTo(Unknown Source)
at java.util.TreeMap.put(Unknown Source)
at Database.insertIntoIndexFile(Database.java:433)
at Database.insertIntoTable(Database.java:369)
at Database.main(Database.java:1340)
Similar stacktrace for each of short, integer etc. I expect the key to be these datatypes. Therefore I have used Object type to store the keys. But I am not trying to cast them String before inserting into the map.
Is there anything that I am overlooking while replacing a hashmap with treemap. I agree its a very broad question but any help would really be great.
Thanks for your time.

Why doesn't reflection set a property in a Struct?

class PriceClass {
private int value;
public int Value
{
get { return this.value; }
set { this.value = value; }
}
}
struct PriceStruct
{
private int value;
public int Value
{
get { return this.value; }
set { this.value = value; }
}
}
static void Main(string[] args)
{
PriceClass _priceClass = new PriceClass();
Type type = typeof(PriceClass);
PropertyInfo info = type.GetProperty("Value");
info.SetValue(_priceClass, 32, null);
Console.WriteLine(_priceClass.Value);
PriceStruct _priceStruct = new PriceStruct();
type = typeof(PriceStruct);
info = type.GetProperty("Value");
info.SetValue(_priceStruct, 32, null);
Console.WriteLine(_priceStruct.Value);
Debugger.Break();
}
The first value printed is 32 while the second is 0. No exception thrown
It's because boxing your struct makes a copy of it, so you should box it earlier so you call the getter from the same data that you modified. The following code works:
object _priceStruct = new PriceStruct(); //Box first
type = typeof(PriceStruct);
info = type.GetProperty("Value");
info.SetValue(_priceStruct, 32, null);
Console.WriteLine(((PriceStruct)_priceStruct).Value); //now unbox and get value
Debugger.Break();
structs are ValueTypes, which are passed by value, that means you only pass around copies of the entire struct, not a reference to the original object.
So when you pass it into info.SetValue(_priceStruct, 32, null), a copy is passed to the method and mutated, so the original object doesn't get changed at all. Another reason why mutable structs are evil.
You can still change them using reflection but it is a bit long winded.
See this example: http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/2dd4315c-0d0d-405c-8d52-b4b176997472

How to determine via UIAutomation, whether a button is pressed or not?

I want to find out whether a button is pressed or not. This seems not to be an official property of a button (not a button-style checkbox!), but seems accessible, there is the BM_GETSTATE message for example that should get the desired result.
Problem is, frequently, I dont get window-handles for my buttons (they are just part of another Toolbar, though they can be distinguihed by the AutomationElement). And I would need such a handle for the SendMessage function.
So.. is there a way for me to access that property? I know it is accessible, since I have seen it in other automation-programmes, I just dont konw how to get at it.
I am going to use C#, but any C code would be fine.
Many thanks
(edit: so I finally managed to make the code format properly here - just insert 4 spaces at the beginning.)
Enjoy it, it took me quite a long time to get it to work.. but now I feel like having reached a new level. :)
(please tell me how to make it format properly - both quote and code failed on me)
int res;
#region direct method
int hwnd = ae.Current.NativeWindowHandle;
if (hwnd != 0)
{
const UInt32 BM_GETSTATE = 0x00F2;
res = SendMessage(hwnd, BM_GETSTATE, 0, 0);
}
#endregion
else
#region method via toolbar
{
AutomationElement parent = TreeWalker.RawViewWalker.GetParent(ae);
while ((parent != null) && (parent.Current.ControlType != ControlType.ToolBar))
parent = TreeWalker.RawViewWalker.GetParent(ae);
if (parent != null)
{
int toolBarHandle = parent.Current.NativeWindowHandle;
#region defines
const int WM_USER = 0x400;
const int TB_GETSTATE = (WM_USER + 18);
const int TB_GETBUTTON = (WM_USER + 23);
const int TB_BUTTONCOUNT = (WM_USER + 24);
#endregion
#region get correct child number
int numButtons = SendMessage(toolBarHandle, TB_BUTTONCOUNT, 0, 0);
AutomationElement sibling = ae;
int cnt = -1;
while (sibling != null)
{
sibling = TreeWalker.RawViewWalker.GetPreviousSibling(sibling);
++cnt;
}
if (cnt >= numButtons)
cnt = 0; // nonsense value, but pass a valid one
#endregion
#region get command id
TBBUTTON butInfo = new TBBUTTON();
butInfo.idCommand = 1234;
uint pid;
GetWindowThreadProcessId((IntPtr)toolBarHandle, out pid);
IntPtr process = OpenProcess(ProcessAccessFlags.VMOperation | ProcessAccessFlags.VMRead |
ProcessAccessFlags.VMWrite | ProcessAccessFlags.QueryInformation, false, pid);
IntPtr p = VirtualAllocEx(process, IntPtr.Zero, (uint)Marshal.SizeOf(typeof(TBBUTTON)), AllocationType.Commit
, MemoryProtection.ReadWrite);
int _res = SendMessage(toolBarHandle, TB_GETBUTTON, cnt, p.ToInt32());
#region getresult
int read;
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TBBUTTON)));
Marshal.StructureToPtr(butInfo, ptr, true);
bool __res = ReadProcessMemory(process, p, ptr, Marshal.SizeOf(typeof(TBBUTTON)), out read);
System.Diagnostics.Debug.Assert(read == Marshal.SizeOf(typeof(TBBUTTON)));
butInfo = (TBBUTTON)Marshal.PtrToStructure(ptr, typeof(TBBUTTON));
#endregion
int commandId = butInfo.idCommand;
VirtualFreeEx(process, p, 0, FreeType.Release);
#endregion
//!define BST_UNCHECKED 0
//!define BST_CHECKED 1
//!define BST_INDETERMINATE 2
//!define BST_PUSHED 4
//!define BST_FOCUS 8
#region get state
res = SendMessage(toolBarHandle, TB_GETSTATE, commandId, 0);
#endregion
}
}
#endregion
EDIT:
Here http://www.andreas-reiff.de/2011/06/c-speicher-anderen-prozess-befullen-lassen-checken-ob-ein-button-gedruckt/ with readable code and explanations in a strange, foreign language.. code comments are english, though. hope you find it useful.
Also, I would not have been able to solve this without the info here How come some controls don't have a windows handle?.

How to dynamically set a property of a class without using reflection (with dynamic) in C# 4 when property name is coming from another source

I'm building/updating an EntityFramework EntityObject on runtime. I want to set the properties of the entity class, property names and values are coming from another source.
So I'm doing this;
public static EntityCollection<T> UpdateLocaleEntity<T>(EntityCollection<T> entityCollectionToUpdate, params ILocaleControl[] values) where T : EntityObject
{
foreach (var x in entityCollectionToUpdate)
{
Type t = typeof(T);
dynamic localeEntity = x;
string cultureCode = localeEntity.CultureCode;
for (int j = 0; j < values.Length; j++)
{
var value = values[j].GetLocaleValue(cultureCode);
t.GetProperty(values[j].EntityPropertyName).SetValue(localeEntity, value, null);
}
}
return entityCollectionToUpdate;
}
So, how can I get rid of "t.GetProperty(values[j].EntityPropertyName).SetValue(localeEntity, value, null);" part, is there a dynamic way of doing this?
Something like;
dynamicCastedLocaleEntity.GetProperty(values[j].EntityPropertyName) = value;
Thanks.
Long answer coming up.
Reflection is great in many situations, horrible in some but in almost all cases it's slow.
There are at least 4 different ways to set a property in .NET without having to use reflection.
I thought I demonstrate one of them: Using compiled expression trees. Note that the expression building is rather expensive too so that's why it's very important to cache the delegate one builds with it in a dictionary (for instance):
Expression Trees was introduced in .NET35 and is used for many things. Here I use them to build a property setter expression and then compile it into a delegate.
The example demonstrates different timing for the different cases but here are my numbers:
Control case (hard coded): 0.02s
Reflection: 1.78s
Expression Tree: 0.06s
using System;
using System.Linq.Expressions;
namespace DifferentPropertSetterStrategies
{
class TestClass
{
public string XY
{
get;
set;
}
}
class DelegateFactory
{
public static Action<object, object> GenerateSetPropertyActionForControl(
)
{
return (inst, val) => ((TestClass) inst).XY = (string) val;
}
public static Action<object, object> GenerateSetPropertyActionWithReflection(
Type type,
string property
)
{
var propertyInfo = type.GetProperty(property);
return (inst, val) => propertyInfo.SetValue (inst, val, null);
}
public static Action<object,object> GenerateSetPropertyActionWithLinqExpression (
Type type,
string property
)
{
var propertyInfo = type.GetProperty(property);
var propertyType = propertyInfo.PropertyType;
var instanceParameter = Expression.Parameter(typeof(object), "instance");
var valueParameter = Expression.Parameter(typeof(object), "value");
var lambda = Expression.Lambda<Action<object, object>> (
Expression.Assign (
Expression.Property (Expression.Convert (instanceParameter, type), propertyInfo),
Expression.Convert(valueParameter, propertyType)),
instanceParameter,
valueParameter
);
return lambda.Compile();
}
}
static class Program
{
static void Time (
string tag,
object instance,
object value,
Action<object, object > action
)
{
// Cold run
action(instance, value);
var then = DateTime.Now;
const int Count = 2000000;
for (var iter = 0; iter < Count; ++iter)
{
action (instance, value);
}
var diff = DateTime.Now - then;
Console.WriteLine ("{0} {1} times - {2:0.00}s", tag, Count, diff.TotalSeconds);
}
static void Main(string[] args)
{
var instance = new TestClass ();
var instanceType = instance.GetType ();
const string TestProperty = "XY";
const string TestValue = "Test";
// Control case which just uses a hard coded delegate
Time(
"Control",
instance,
TestValue,
DelegateFactory.GenerateSetPropertyActionForControl ()
);
Time(
"Reflection",
instance,
TestValue,
DelegateFactory.GenerateSetPropertyActionWithReflection (instanceType, TestProperty)
);
Time(
"Expression Trees",
instance,
TestValue,
DelegateFactory.GenerateSetPropertyActionWithLinqExpression(instanceType, TestProperty)
);
Console.ReadKey();
}
}
}
For FuleSnabel's answer, you can speed it up a lot (sometimes twice as fast in my tests). In some tests, it was just as fast as the Control solution:
public static Action<Object,Object> GenerateSetPropertyActionWithLinqExpression2(Type type, String property) {
PropertyInfo pi = type.GetProperty(property,BindingFlags.Instance|BindingFlags.Public);
MethodInfo mi = pi.GetSetMethod();
Type propertyType = pi.PropertyType;
var instance = Expression.Parameter(typeof(Object), "instance");
var value = Expression.Parameter(typeof(Object), "value");
var instance2 = Expression.Convert(instance, type);
var value2 = Expression.Convert(value, pi.PropertyType);
var callExpr = Expression.Call(instance2, mi, value2);
return Expression.Lambda<Action<Object,Object>>(callExpr, instance, value).Compile();
}
possibly not with EntityObject, but if you've had an ExpandoObject than you can do
dynamic entity = new ExpandoObject();
(entity as IDictionary<String, Object>)[values[j].EntityPropertyName] = value
The open source framework ImpromptuInterface has methods to invoke based on a string using the DLR rather than reflection and runs faster than reflection too.
Impromptu.InvokeSet(localeEntity, values[j].EntityPropertyName,value);
I'm afraid not. Any use of a dynamic object is baked-in at compile time. Any call which could vary at run-time has to be done using reflection.

Resources