LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

CAN Intrepid 64 bits API

Solved!
Go to solution

I've used the VIs of hoovahh to send signals through Intrepid HW and it works correctly in Labview 32 bits but I want to use it with Labview 64 bits. The problem is the DLL is only for 32 bits, I found another dlls but when I tried to select it I got an error due dll incompatibility (the dll is only for 32 and not for 64 as it was supposed to)

Do anyone have the dll for 64 bits?

0 Kudos
Message 1 of 8
(895 Views)
Solution
Accepted by topic author Alfredo_VM

(Crap another thing on my todo list) 

 

Intrepid has supported 32 and 64 bit versions of their DLL for interfacing with their hardware for a while.  But once they added CAN FD the payloads could be very large, and the strategy changed from returning data from a read, to returning an address of where the data was stored.  This in itself isn't an issue, but they provided a Helper.dll for doing the defreferencing part of the code.  And this helper.dll is only a 32 bit version.  So to support 64 bit and CAN FD you either need a 64 bit version of the helper.dll or to remove the requirement for it.  I contacted support about a 64 bit version but they said they didn't have one.

 

I believe this is the newest release.  When in the 64 bit version of LabVIEW they require a Helper.dll.  I don't deal much with C, but I do believe the Helper.dll is attempting to dereference data.  Here is a document on NI.com that talks about the different options, with the MoveBlock being the most likely one to work well.

 

https://forums.ni.com/t5/Developer-Center-Resources/Dereferencing-Pointers-from-C-C-DLLs-in-LabVIEW/...

 

I started a journey to updating the code to be 64 bit and CAN FD, and I thought I made progress but looking back it seems I never finished it.

0 Kudos
Message 2 of 8
(854 Views)

By the moment I'm avoiding CAN FD (I only need CAN FD). I've added a conditional disable structure an updated the dll but the api doesn't work (even in the 32 bits version). I've checked the issue and it happened due I'm using a Value CAN 4-2 and it has not been declarated in the initialization, I've added the value of the hw and the value can has been found.

Alfredo_VM_0-1709658668118.png

Also I had to modify the Neo Device Cluster to use Open Device.vi

Alfredo_VM_1-1709658723556.png

 

The problem is at the moment I send a message, I receive a 0 from the dll (it means a error) 

Alfredo_VM_2-1709658821035.png

and after check the documentation I saw the structure of the SpyMessage is different

Alfredo_VM_3-1709659010799.png

Alfredo_VM_4-1709659045538.png

Do you recommend to adapt the cluster to the new SpyMessage? Or do you think the error is due another thing (I didn't mentioned that any vi, except find devices and open driver, returned 0 value so the vi sends a error

 

 

 

0 Kudos
Message 3 of 8
(739 Views)

Attached is some code you might find helpful.  It is unreleased, and I'm unsure what state it is in.  It has a separate set of examples for LabVIEW 32 and LabVIEW 64 bit.  I did make some changes to the LabVIEW 32 bit version in the hopes that it could be used as one example for both platforms.  I'm unsure if it works well enough I don't remember if I finished it.  My suggestion is to try to run the 32 bit example first opening the NEO VI Example.vi.  DLL relinking might be needed.  I tried making unique DLL names adding "64" to end of the DLL name for the 64 bit platform.  If that doesn't work or gives you problems go and try the 64 Bit example which is inside the LLB.

 

One thing I tried improving is the fact that CAN FD messages have a pointer to the data instead of containing the data itself.  Intrepid then had a "Helper.dll" which was intended to take the pointer and return the actual data.  I don't have the source to this DLL and am unsure how it works, but from experimentation it seems it works the same way as the LabVIEW MoveBlock.  So that's what I tried adding to the 32 bit example, to make it compatible with either 32 or 64 bit.

 

This example maybe dated, and Intrepid may have released newer versions online, but I can't find any.  This is several years old and so I hope they don't mind me posting it since there isn't really any other examples online.  Please don't bug them if this particular example doesn't work, but it can be used as a guide in the data structure and how it should work.

 

EDIT: Also the DLLs are quite large and make distribution a pain.  The DLLs with the firmware is roughly 150MB for each platform.

0 Kudos
Message 4 of 8
(730 Views)

Thanks. The helper dll will be very useful in the future. And my error was due the hobject of the dll was in I32, with I64 works correctly

0 Kudos
Message 5 of 8
(709 Views)

hobject sounds like a HANDLE. This is a pointer sized data type, so you should configure it as such in the Call Library Node. If you configure it as U/I64 instead, the VI will do very bad things if you ever try to run it in 32-bit again.

 

And yes I know: I'm never going back to 32-bit so why care?

 

Famous last words! 😁

It's a small effort and may save you a lot of pain in the future, when you have to get something run on that old Windows 10 machine where only LabVIEW 32-bit was installed.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 8
(697 Views)

@rolfk wrote:

hobject sounds like a HANDLE. This is a pointer sized data type, so you should configure it as such in the Call Library Node. If you configure it as U/I64 instead, the VI will do very bad things if you ever try to run it in 32-bit again.


I don't understand where this advice needs to be applied to.  I'm aware that a handle can vary in the datatype based on the environment it is running on.  So I understand you are saying the handle needs to be a U32 on the 32-bit, and a U64 on the 64-bit runtimes.  Are you saying you found some place that I'm doing something wrong?  This isn't an area I'm entirely comfortable with and usually just flounder around until something starts working.

0 Kudos
Message 7 of 8
(655 Views)

@Hooovahh wrote:

@rolfk wrote:

hobject sounds like a HANDLE. This is a pointer sized data type, so you should configure it as such in the Call Library Node. If you configure it as U/I64 instead, the VI will do very bad things if you ever try to run it in 32-bit again.


I don't understand where this advice needs to be applied to.  I'm aware that a handle can vary in the datatype based on the environment it is running on.  So I understand you are saying the handle needs to be a U32 on the 32-bit, and a U64 on the 64-bit runtimes.  Are you saying you found some place that I'm doing something wrong?  This isn't an area I'm entirely comfortable with and usually just flounder around until something starts working.


When you configure an integer parameter in the Call Library Node, you can also specify its size. If you configure this as U32 or U64, it will always be passed as such to the DLL, irrespective on the bitness of LabVIEW/DLL. For pointer sized variables this is bad!

If it is configured as U32, the upper 32-bit of the value will be simply truncated, potentially making the handle invalid. For some Windows datatypes such as window handles, this is supposedly not an issue as Microsoft claimed somewhere to make sure the handle value is always smaller than 0xFFFFFFFF. But I have not confirmed that and don't intend to do it as it is simply The Right(TM) thing to configure them correctly anyways and not rely on some strange assurance that can change any moment, if it is even true. For other libraries, handles are very often (opaque) pointers to real memory and therefore easily can have values that are definitely above 0xFFFFFFFF in 64-bit mode and cutting off the upper 32-bit will cause corrupted memory addresses.

If it is configured as U64, it will work in 64-bit application mode without trouble, but when executed in 32-bit mode it will split it into two 32-bit integers and pass them as two 32-bit values on the stack. And bamm, your stack is misaligned with what the function, as it only expects one 32-bit value on the stack. Any subsequent parameter of the function will be 4 bytes off, and your function only sees them as trash.

 

On the LabVIEW diagram (and front panel) you do need to use U64 (or I64) controls/indicators since LabVIEW itself does not know a Pointer type value. The Call Library Node will make sure to pass the lower 32-bit of this value to the DLL, when running in a 32-bit application, and properly sign-extend the 32-bit value to 64-bit on return of such a value, if it is configured as pointer sized value.

 

And the comment was mainly directed at Alfredo. He seems to have simply changed everything to an I64, which will work on 64-bit but would cause problems if he ever needs to run those VIs in 32-bit again.

Rolf Kalbermatter
My Blog
0 Kudos
Message 8 of 8
(650 Views)