From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to determine memory address of an array

Nice work! I feel a bit bad suggesting a much simpler way to accomplish some of what you've done there, but it's a trick worth knowing for future use: unflatten from string can be used to convert an array of bytes to a cluster so long as that cluster contains only fixed-size elements. It will even swap endianness for you.

 

For example, in your Parse_IP_ADAPTERS_ADDRESSES.Unpack.vi, you can replace the for loop with unflatten from string. You will need to make one change to the IP_ADAPTER_INFO cluster: replace the arrays (such as Skip2 44) with fixed-size clusters that contain the correct number of bytes. You can nest that Skip cluster inside the main cluster. A quick way to generate a cluster like this is to wire an empty array of the appropriate data type to "Array to Cluster," set the cluster size to the right size, and create a constant.

 

Make one call to MoveBlock, moving the entire structure at once into an array of bytes, then use Byte Array to String. Wire that string to Unflatten from String, and set the endianness input appropriately. Give it a try - I think you'll find it's a much simpler, cleaner method than the for loop.

 

Also, a note about for loops (I noticed one instance of this in your code in a quick look) - when you use array auto-indexing, there is no need to also wire the N iterations terminal, especially not wired to an array length function that's returning the length of the auto-indexed array.

0 Kudos
Message 11 of 18
(811 Views)

@rolfk wrote:

The most painful part of this, will be that there is no way of making this work for both 32 bit and 64 bit Windows without seperate code for each. This is because LabVIEW does not know a datatype that can be added as cluster element whose size is platform dependent. The easier and more portable approach would be to write an intermediate DLL in C, that translates between a more LabVIEW friendly array of data structures, and the one the WinAPI uses.


rolfk, thanks for your input, I'm concerned about portability.  I had built a wrapper DLL, but it meant deploying an additional file (the DLL) with installer.  On deployment, the VI was broken due to additional DLL dependencies caused by my dll.  I went this all-LabVIEW route because it eliminates multiple additional DLL dependencies (msvcrt.dll, msvcr100d.dll, iphlpapi.dll, to name a few.)

 

Your comment about not working for both 32 and 64 bit is most troubling, though, I don't understand why this approach requires a platform-dependent cluster element.  Please have a look at the code - I'm anxious to understand potential problems!  

 

Thanks/Cheers!

0 Kudos
Message 12 of 18
(808 Views)

@nathand wrote:

Nice work! I feel a bit bad suggesting a much simpler way to accomplish some of what you've done there, but it's a trick worth knowing for future use: unflatten from string can be used to convert an array of bytes to a cluster so long as that cluster contains only fixed-size elements. It will even swap endianness for you.

 

For example, in your Parse_IP_ADAPTERS_ADDRESSES.Unpack.vi, you can replace the for loop with unflatten from string. You will need to make one change to the IP_ADAPTER_INFO cluster: replace the arrays (such as Skip2 44) with fixed-size clusters that contain the correct number of bytes. You can nest that Skip cluster inside the main cluster. A quick way to generate a cluster like this is to wire an empty array of the appropriate data type to "Array to Cluster," set the cluster size to the right size, and create a constant.

 

Make one call to MoveBlock, moving the entire structure at once into an array of bytes, then use Byte Array to String. Wire that string to Unflatten from String, and set the endianness input appropriately. Give it a try - I think you'll find it's a much simpler, cleaner method than the for loop.

 

Also, a note about for loops (I noticed one instance of this in your code in a quick look) - when you use array auto-indexing, there is no need to also wire the N iterations terminal, especially not wired to an array length function that's returning the length of the auto-indexed array.


Thanks for the idea about (essentially) casting serialized-data to IP_ADAPTERS_ADDRESSES cluster - that will simplify code considerably. Smiley Happy

Re wiring 'N' and auto-indexing.  I think I wired a constant to 'N' during debug, then racing-through to rip-out debug-code, deleted the constant and wired it's natural replacement - array-size! DOH!

 

Thanks/Cheers!

0 Kudos
Message 13 of 18
(804 Views)

@550nm wrote:

Your comment about not working for both 32 and 64 bit is most troubling, though, I don't understand why this approach requires a platform-dependent cluster element.  Please have a look at the code - I'm anxious to understand potential problems!  


LabVIEW has no pointer-sized data type. You can include a 32-bit value in your cluster, or a 64-bit value, but there's no way to tell it to use one on a 32-bit platform and the other on a 64-bit platform. The cluster itself needs to be a different size depending on the platform.

 

I haven't thought it through completely, but I think you can avoid a lot of the problem by having two nearly-identical clusters, one for each platform, and using the unflatten approach. When you unflatten the 32-bit version, I think you could then wire it to a tunnel (in a case structure) that expects the 64-bit version, and LabVIEW will handle the conversion for you (since all the elements will be the same, some will just have a different numeric representation). I might be missing something, though.

0 Kudos
Message 14 of 18
(803 Views)

It's a great idea to have the code adapt to the environment. Questions (for me) now are,

1) what environmental factors are important - I assume the bitness of the hardware and the OS could be, and

2) how to translate those factors into expected pointer-size

0 Kudos
Message 15 of 18
(792 Views)

Not sure whether I should be surprised, but this LabVIEW logic seems to be functioning correctly on a 64bit OS.

It's compiled on Windows 7 32bit and [seems to be] running correctly on Windows 7 64bit...

0 Kudos
Message 16 of 18
(754 Views)

@550nm wrote:

Not sure whether I should be surprised, but this LabVIEW logic seems to be functioning correctly on a 64bit OS.

It's compiled on Windows 7 32bit and [seems to be] running correctly on Windows 7 64bit...


Yes - because even though the operating system is 64-bits, your compiled application is running in a 32-bit environment. See Running 32-bit Applications. The challenge comes when you install a 64-bit version of LabVIEW and then try to run your VI within that 64-bit environment.

Message 17 of 18
(744 Views)

Thanks nathand.

I never before noticed there are two versions API DLLs on 64bit machines.

I think I see the light! Smiley Wink

0 Kudos
Message 18 of 18
(730 Views)