I have some c code with me which detects the usb cable removal and insertion.
I found one structure DEV_BROADCAST_DEVICEINTERFACE which is having dbcc_name as member. but I don't know which pointer to type cast to this structure to access dbcc_name.
How can I get the device name of the inserted device.
You need to cast a DEV_BROADCAST_HEADER* to a DEV_BROADCAST_DEVICEINTERFACE*. You are allowed to do so if and only if dbch_devicetype==DBT_DEVTYP_DEVICEINTERFACE.
You getDEV_BROADCAST_HEADER* as the LPARAM of WM_DEVICECHANGE.
To do something useful with dbcc_name, you have to pass it to SetupDiOpenDeviceInterface(). This will give you a SP_DEVICE_INTERFACE_DATA with one SP_DEVINFO_DATA. You can then call functions like SetupDiGetDeviceRegistryProperty to learn more about the device.
Please notice the CodeSet. If it is Unicode. The data is \\0......
Related
Can I call a function from LabVIEW that is at certain ordinal in some DLL, while the ordinal is determined at run-time?
I'm also interested if there is something similar to function pointers, like in 'C' language, which hold some dynamic function address?
If your intention is to call function by address, you will have to develop a wrapper in C by compiling a DLL from a code like that:
typedef int (*real_func_type)(int);
int wrapper(size_t address, int param1)
{
return ((real_func_type)address)(param1);
}
where real function proto is
int real_func(int param);
If your second question is whether LabVIEW has something similar to a function pointer, then the answer is that the closest thing is a VI reference. There are different types of VI references and different ways of creating and using them, so you would need to read up on that.
In any case, VI references are purely a LabVIEW construct. There's no mechanism for interacting with C function pointers directly and you can't create a function pointer to a VI and give that to the DLL function. For something like that you would also need some wrappers.
In your block diagram, create a case structure that takes your ordinal value. In each frame of the case structure, invoke the appropriate function from the DLL.
I am trying to interface with a USB device that provides an external C++ dll file and have read a myriad of articles surrounding delegates, marshalling, pointers and I generally get the idea of what is happening. Unfortunately, my practical experience in this area is letting me down in obtaining the final solution.
I have connected to the device in order to create a session successfully but there is a function called EnumDevices which supposedly enumerates the device list for specific future calls. The function has a function within itself that lists the devices and it is this part I am struggling with.
The enumdevices call in the API looks like this:
EnumDevices(INTERFACE,FoundDevice,NULL);
bool __stdcall FoundDevice(long data, const char *DeviceName)
{
printf("device name %s\n", DeviceName)
Return True
}
and according to the documentation, FoundDevice is a call back method called for each found device.
In VB.Net, what I have done is as follows:
Created a delegate function
Delegate Function FoundDeviceDelegate(data as integer, DeviceName as PInvoker.Marshal.ByteArrayPtr) as Boolean
Then I created a local function with the same signature
Private Function FoundDevice(data as integer, DeviceName as PInvoker.Marshal.ByteArrayPtr) as Boolean
Msgbox(DeviceName.ToString)
Return True
End Function
In my main code, I make the following declarations and calls
dim devhandler as assembly.FoundDeviceHandler = AddressOf FoundDevice
dim device as new assembly.FoundDevice(devhandler)
assembly.EnumDevices(INTERFACE,device,vbNull)
('assembly' is the reference to the external dll, 'INTERFACE' is a constant and 'device' expects a function with the two parameters - user and devicename)
I thought that the EnumDevices call would then pass back to the device reference which in turns calls the DeviceHandler which references the delegated function which would then output the device name.
What I have got is a pointer value on 'device' but I am struggling referencing this back to a device name. It is never executing the FoundDevice function to show the messagebox.
I have read so much that I think I have read too much surrounding delegates and marshalling etc that I am now struggling to get to the end which feels so close given that I have the pointer reference when I debug it.
If anyone can make sense of the above and provide any useful assistance, it would be very much appreciated.
I maintain a program which can be automated via COM. Generally customers use VBS to do their scripting, but we have a couple of customers who use Matlab's ActiveX support and are having trouble calling COM object methods with a NULL parameter.
They've asked how they do this in Matlab - and I've been scouring Mathworks' COM/ActiveX documentation for a day or so now and can't figure it out.
Their example code might look something like this:
function do_something()
OurAppInstance = actxserver('Foo.Application');
OurAppInstance.Method('Hello', NULL)
end
where NULL is where in another language, we'd write NULL or nil or Nothing, or, of course, pass in an object. The problem is this is optional (and these are implemented as optional parameters in most, but not all, cases) - these methods expect to get NULL quite often.
They tell me they've tried [] (which from my reading seemed the most likely) as well as '', Nothing, 'Nothing', None, Null, and 0. I have no idea how many of those are even valid Matlab keywords - certainly none work in this case.
Can anyone help? What's Matlab's syntax for a null pointer / object for use as a COM method parameter?
Update: Thanks for all the replies so far! Unfortunately, none of the answers seem to work, not even libpointer. The error is the same in all cases:
Error: Type mismatch, argument 2
This parameter in the COM type library is described in RIDL as:
HRESULT _stdcall OurMethod([in] BSTR strParamOne, [in, optional] OurCoClass* oParamTwo, [out, retval] VARIANT_BOOL* bResult);
The coclass in question implements a single interface descending from IDispatch.
I'm answering my own question here, after talking to Matlab tech support: There is no equivalent of Nothing, and Matlab does not support this.
In detail: Matlab does support optional arguments, but does not support passing in variant NULL pointers (actually, to follow exactly how VB's Nothing works, a VT_EMPTY variant, I think) whether as an optional argument or not. There is documentation about some null / pointerish types, a lot of which is mentioned in my question or in various answers, but these don't seem to be useable with their COM support.
I was given a workaround by Matlab support using a COM DLL they created and Excel to create a dummy nothing object that could be passed around in scripts. I haven't managed to get this workaround / hack working, and even if I had unfortunately I probably could not redistribute it. However, if you encounter the same problem this description might give you a starting point at least!
Edit
It is possible this Old New Thing blog post may be related. (I no longer work with access to the problematic source code, or access to Matlab, to refresh my memory or to test.)
Briefly, for IUnknown (or derived) parameters, you need a [unique] attribute for them to legally be NULL. The above declaration required Matlab create or pass in a VT_EMPTY variant, which it couldn't do. Perhaps adding [unique] may have prompted the Matlab engine to pass in a NULL pointer (or variant containing a NULL pointer), instead - assuming it was able to do that, which is guesswork.
This is all speculation since this code and the intricacies of it are several years behind me at this point. However, I hope it helps any future reader.
From the mathworks documentation, you can use the libpointer function:
p = libpointer;
and then p will be a NULL pointer. See that page for more details.
See also: more information about libpointer.
Peter's answer should work, but something you might want to try is NaN, which is what Matlab ususally uses as a NULL value.
In addition to using [] and libpointer (as suggested by Peter), you can also try {}.
The correct answer for something in VB that is expecting a Nothing argument, is to somehow get a COM/ActiveX Variant which has a variant type of VT_EMPTY. (see MSDN docs which reference marshaling behavior for Visual Basic Nothing)
MATLAB may do this with the empty array ([]), but I'm not sure.... so it may not be possible purely in MATLAB. Although someone could easily write a tiny COM library whose purpose is to create a Variant with VT_EMPTY.
But if the argument has the [optional] atttribute, and you want to leave that optional argument blank, you should not do this. See the COM/ActiveX docs on Variants which say under VT_EMPTY:
VT_EMPTY: No value was specified. If an optional argument to an Automation method is left blank, do not pass a VARIANT of type VT_EMPTY. Instead, pass a VARIANT of type VT_ERROR with a value of DISP_E_PARAMNOTFOUND.
Matlab should (but probably does not) provide methods to create these objects (a "nothing" and an "optional blank") so you can interface correctly with COM objects.
I am trying to trace managed object creation/disposing in a CLI/C++ prog:
::System::Diagnostics::Trace::WriteLine(String::Format(
"Created {0} #{1:X8}",
this->GetType()->Name,
((UInt64)this).ToString()));
Which fails with
error C2440: 'type cast' : cannot convert from 'MyType ^const ' to 'unsigned __int64'
Is there a way to keep track of the unique object IDs this way?
Thanks!
First of all, why this doesn't work. Managed handle types ^ aren't pointers. They aren't just addresses. An instance of a managed type can and will be moved around in memory by GC, so addresses aren't stable; hence why it wouldn't let you do such a cast (as GC can execute at any moment, and you do not know when, any attempt to use such an address as a raw value is inherently a race condition).
Another thing that is often recommended, but doesn't actually work, is Object.GetHashCode(). For one thing, it returns an int, obviously not enough to be unique on x64. Furthermore, the documentation doesn't guarantee that values are unique, and they actually aren't in 2.0+.
The only working solution is to create a an instance of System.Runtime.InteropServices.GCHandle for your object, and then cast it to IntPtr - that is guaranteed to be both unique, and stable.
Check out the GCHandle type: http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx. Looks like it would do what you want, though it looks it would be a bit of a pain to use for your purposes...
Even if you could cast this to some integral value for display, it probably wouldn't be a useful unique identifier. This is because unlike C++, in C++/CLI the location of a (managed) object (and by extension the value of this) can potentially change during that object's lifetime. The (logically) same object could print two different strings at different points in the program.
MyType ^const is a reference type. Hence it's in the managed memory space, and you can't get direct memory pointers to these types, as they can change at any time.
Is there a way to keep track of the unique object IDs this way? Thanks!
You could use MyType.GetHashCode();
What is the most similar thing in VB.NET to a pointer, meaning like C pointers?
I have a TreeView within a class. I need to expose some specific nodes (or leaves) that can be modified by external objects.
C#, and I also believe VB.Net, will work on the concept of references. Essentially, it means when you say
A a = new A()
the 'a' is a reference, and not the actual object.
So if I go
B b = a
b is another reference to the same underlying object.
When you want to expose any internal objects, you can simply do so by exposing 'properties'. Make sure, that you do not provide setters for the properties, or that if you do, there is code to check if the value is legal.
ByRef is used when you want to pass the object as a parameter, and when you want the called method to be able to change the reference (as opposed to the object).
As mentioned above, if you post some code, it will be easier to explain.
Nathan W has already suggested the IntPtr structure which can represent a pointer or handle, however, whilst this structure is part and parcel of the .NET framework, .NET really doesn't have pointers per-say, and certainly not like C pointers.
This is primarily because the .NET Framework is a "managed" platform and memory is managed, assigned, allocated and deallocated by the CLR without you, the developer, having to worry about it (i.e. no malloc commands!) It's mostly because of this memory management that you don't really have access to direct memory addresses.
The closest thing within the .NET Framework that can be thought of as a "pointer" (but really isn't one) is the delegate. You can think of a delegate as a "function pointer", however, it's not really a pointer in the strictest sense. Delegates add type-safety to calling functions, allowing code that "invokes" a delegate instance to ensure that it is calling the correct method with the correct parameters. This is unlike "traditional" pointers as they are not type-safe, and merely reference a memory address.
Delegates are everywhere in the .NET Framework, and whenever you use an event, or respond to an event, you're using delegates.
If you want to use C# rather than VB.NET, you can write code that is marked as "unsafe". This allows code within the unsafe block to run outside of the protection of the CLR. This, in turn, allows usage of "real" pointers, just like C, however, they still do have some limitations (such as what can be at the memory address that is pointed to).
Best way to do it is to just allocate everything manually:
You can move up OR down each Stack at free will without Pushing or Popping.
Dim Stack(4095) as Byte 'for 8bit - 1 bytes each entry
Dim Stack(4095) as Integer 'for 16bit - 2 bytes each entry
Dim Stack(4095) as Long 'for 32bit - 4 bytes each entry
Dim Stack(4095) as Double 'for 64 bit - 8 bytes each entry
Dim i as integer 'Where i is your Stack Pointer(0 through 4095)
Dim int as integer 'Byte Integer Long or Double (8, 16, 32, 64 bit)
for i = 0 to 4095
int = i
Stack(i) = int/256 'For 8bit Byte
Stack(i) = int 'For 16bit Integer
Stack(i) = Microsoft.VisualBasic.MKL$(int) 'For 32bit Long
Stack(i) = Microsoft.VisualBasic.MKD$(int) 'For 64bit Double
MsgBox(Microsoft.VisualBasic.HEX$(Stack(i))) 'To See Bitwise Length Per Entry
next i
If you're looking to pass something back from a subroutine you can pass it by reference - as in "ByRef myParamter as Object".
Best answer depends, to some degree, on what you're trying to do.
If you are using VB the only thing that is really close to a pointer is a IntPtr. If you have access to C# you can use unsafe C# code to do pointer work.