I work with the registry and use the function RegNotifyChangeKeyValue. The first option requires registry key handle (HKEY), but I have RegistryKey, from which I can get SafeRegistryKey (key->Handle).
RegistryKey^ key = myKey;
RegNotifyChangeKeyValue(key->Handle, true, dwFilter, events[i], true);
Error: "argument of type "Microsoft::Win32::SafeHandles::SafeRegistryHandle" is incompatible with parameter of type "HKEY""
How do I get HKEY?
A conversion is required to get from the wrapped IntPtr in the safe-handle class to the native handle. It looks like this:
HKEY handle = (HKEY)key->Handle->DangerousGetHandle().ToPointer();
You do get to fret over the word "Dangerous" in the method name, it is aptly named. There is nothing that the CLR can do to ensure that the handle stays valid until you no longer need the change notifications. It is now your job to ensure that the key object reference stays visible and the garbage collector won't collect it too early.
It cannot be a local variable, it could be a member of a class but that in turn requires the class object to stay referenced. Storing it in a static variable is the safest way, calling GCHandle::Alloc() is the next best way, maybe you need gcroot<>. There's no context in the question to make the call.
Related
Background: I've got a set of VB6 DLLs that share a common "interface". Whichever version is installed locally has members of this interface invoked via COM interop (from VB.Net code, which I suspect might matter). I noticed today that one of the invocations passes [what I understand to be] an rvalue (hereinafter "an rvalue") to a VB6 function that does not have that particular parameter defined as ByVal.
Example Code:
VB6:
Public Function VB6Function(input As String) As String
' Do interesting things with input
End Function
VB.Net:
' get an instance of the VB6 class and pass our trimmed localString to it
result = vb6Instance.VB6Function(localString.Trim())
' Do interesting things with localString
I have not yet noticed an instance of the VB6 code changing the value of input, but I also haven't done an exhaustive search of the different DLL implementations (there are several hundred).
What would happen if VB6Function did change the value of input when input is "an rvalue"? For that matter, why doesn't this method invocation simply error out when "an rvalue" is passed?
What would happen if VB6Function did change the value of input when input is "an rvalue"?
Nothing. Or rather, nothing interesting.
When the called function changes the value of its argument, it makes no difference for the insides of that function whether the argument was provided byval or byref. All that matters is that there is a variable of certain type, thus, it can be acted upon.
For that matter, why doesn't this method invocation simply error out when "an rvalue" is passed?
Why would it error out? The passed argument as correct type (string), that is all that matters.
There is no notion of an rvalue in VB.
When you pass what you would call an rvalue to a method accepting something by reference, the compiler automatically passes the reference to a temporary location where the rvalue actually resides. The method gets its value byref, the caller does not care about pointers.
localString.Trim() allocates and returns a string. It has an address and can be passed around. Your code does not explicitly capture that address, but the compiler has no problem passing it to VB6Function byref. If VB6Function changes the value, it changes what that temporary location points to, which has no observable difference because it's going to be destroyed after the call either way.
As for why some people may have preferred receiving strings byref in VBA, it's specifically to avoid copying the entire string each time when calling the function. In VB.NET it's not a problem because strings there are immutable and therefore can be passed byval without copying, but in VBA that is not the case, so a byval string needs to be cloned for the purpose of the call. People avoided that by specifying byref, even though that technically gave them the power to mess with the passed variable.
I am writing a jvmti agent for java programs.I am trying to read objects on the stack.Using jnienv pointer received on VMinit/vmstart event.
I succeeded in reading objects upon methodexit event using the foll:
get varaible (slot) from getlocalvariableentry() ;
from the variable signature use jni functions to get object, use getlocalobject function for a reference object/subclass of object.Then if its a subclass of object; jni::getobjectclass(); use returned class and obtain fields in the class;
using getclassfields(); then get field signature from getfieldname(); then call appropriate function for the field as per its signature eg getintfield() for int field.
Howver once I try this upon Objects created within a try block within the function for which methodexit event is raised; I get a crash(SIGSEGV) everytime at Getobjectclass() .Is this because the object has gotten destroyed being out of scope; If so how to read values of variables in a try block of a function at function exit.
obtain crash when upon reading a jobject for Integer (from localvariabletableentry) object , I call getintfield() for its int field member MIN_VALUE which is its first member.If I just try to read member "value" of Integer class then calling getintfield() does not crash.
Is this crash because Im trying to read a static final member of a class ie. member MIN_VALUE Of integer class.
How to come around this and avoid the crashes?
I've used dictionaries (Whether they were called that or not) in a number of other languages, but there's always been a method that can be called with on parameter that either:
A) Returns the associated value if the parameter is in use as a key, or
B) Indicates in some way that the parameter is not used as a key
I've been forced into a position where I have to learn excel/VBA and used the collections class for all of about five minutes before the lack of an .exists method led me to look for something else. The general consensus seems to be that the scripting.Dictionary class is the VBA equivalent of associative arrays/dictionaries/hashtables in other languages.
The one thing I don't like the look of though is that the only way I can see of retrieving the value associated with a given key is to use the .items property (either explicitly, or via scripting.Dictionary("key")). But rather than doing anything to indicate the issue if key is not in use in the dictionary, it adds it.
I know I can use a if structure with .exists being the test to achieve the same functionality, and can write my own function that raises an error if the exists test fails, but it seems a lot of stuffing around to achieve what is core functionality in Python (raises KeyError), PHP (raises a Notice), Java (Maps return null - although that is not necessarily ideal in the case of HashMaps where null actually is a valid value - but it does work as an indicator for HashTables).
So is there any way of attempting to retrieve a value by key that will do something (ideally throw an error) if the key is not in use, rather than silently adding it? Google hasn't provided any answers - but maybe I'm just not phrasing the search well.
I find it inconvenient too that Dictionary adds the key when you access a non-existing key.
Just use Collection and write the missing Exist function yourself, e.g.
Function ExistsInCollection(ByVal c As Collection, ByVal key As Variant) As Boolean
On Error GoTo not_exists
c.Item key
ExistsInCollection = True
not_exists:
End Function
I have a GUI app written in C++/CLI which has a load of configurable options. I have some overloaded functions which grab values from my data source and I'd like to connect my options to those values.
So here's a couple of data retrievers:
bool GetConfigSingle(long paramToGet, String^% str, char* debug, long debugLength);
bool GetConfigSingle(long paramToGet, bool^% v_value, char* debug, long debugLength);
I was hoping to pass in the checkbox's Checked getter/setter as follows:
result = m_dataSource->GetConfigSingle(CONFIG_OPTION1, this->myOption->Checked, debug, debugLen);
...but for some reason I get an odd compiler error which suggests the Checked value isn't being passed as I'd expect:
1>.\DataInterface.cpp(825) : error C2664: 'bool DataInterface::GetConfigSingle(long,System::String ^%, char*, long)' : cannot convert parameter 2 from 'bool' to 'System::String ^%'
Previously this code passed the checkbox in and modified the values itself, but I'm keen to break the dependency our data collection currently has on windows forms.
So what am I missing here?
[Edit] I've filled out the function definitions as they originally were to avoid confusion - my attempt to reduce the irrelevent information failed.
I'm fairly certain that the CheckBox getter / setter returns a bool.
Figured I'd clarify my comments from above and make it a "real" answer...
When you call Checked, what you're getting back as a return value is a bool that represents the current state of the CheckBox. It is not, however, a reference to the actual data member that holds the CheckBox's state. In fact, a properly encapsulated class shouldn't give access to it. Furthermore, since Checked returns a bool by value, that bool is a temporary object that doesn't necessarily exist by the time GetCongigSingle is called.
This leaves you with several options. Either pass the bools by value, and later set the CheckBox's state, or pass the CheckBox itself by reference and "check" it wherever you want.
The two overload of the method GetConfigSingleFile that you have mentioned both take two arguments whereas you are passing 4 arguments to the method. Are there any default arguments? If yes, can you please reproduce the original method declarations?
Most probably, the 4 argument overload of this method is expecting a String^% as the 2nd argument. This is what the compiler is suggesting anyway. But if we can have a look at the method declarations that could help diagnosing the problem.
This isn't an answer to my question, but worth being aware of - apparently there's a quirk in passing properties by reference.
I'm attempting to use an unknown type in a for each loop as per the following code:
private sub ReflectThis(ByVal rawData As Object())
Dim dataType As Type = rawData(0).GetType()
Dim properties As PropertyInfo() = dataType.getProperties()
For Each item As dataType In rawData ''//AAAA
For Each property As System.Reflection.PropertyInfo properties
''//reflected code use here
The issue that I get is on the line marked AAAA. It complains that 'dataType' is not declared, which I take to mean it does not exist as a proper class.
The intent is to call a web service elsewhere, and regardless of which web service I call, use reflection to add the resulting data struct object's information to a database.
What, if any, are the restrictions on doing something like
Dim myObject As variableInstanceOfTypeObjectHere
or am I making a more fundamental error? If I'm right, what are the workarounds, if any?
When you declare a variable "As" a type, that means you know the type at compile time. That lets the compiler check what you're doing with it. In this case, you don't know the type at compile time - you're getting it at execution time. All you know is that each item is an object - so either don't specify the type (as suggested by Joel) or specify it as Object:
For Each item As Object In rawData ''//AAAA
Just don't specify the type:
For Each item in rawData