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: 

Passing a VISA resource to a DLL created in C or LabVIEW

The software I'm developing uses DLLs to control equipment using VISA so that they can be easily interchanged and created by customers. I'm making C templates so a customer can simply fill in commands and create a driver DLL. The problem I'm running into is that I have to pass the VISA resource to the call library node differently depending on if the DLL was created in LabVIEW or C. I do all the opening/closing of the reference in the program, so I want to simply pass the reference to the DLL where only viWrite will be called.

 

If I set the call library node parameter to adapt to type, the LabVIEW created DLL works. If I set it to uint32, the C DLL works. If I switch either, I get "The given session or object reference is invalid."

 

The function call in the C code is: Operate(uintptr_t *VISAresource). I took that from the LabVIEW created header file when building the DLL.

 

So is there something I'm not getting to be able to call both types of DLL from the same call library node? I'd hate to have to incorporate both calls in my code.

0 Kudos
Message 1 of 21
(4,348 Views)

Are you able to pass a string with VISA Resource Name instead of generating a VISA reference and passing that? VISA works with strings too - for example, passing a string with value "ASRL4::INSTR" will allow you to communicate with that instrument type on comport4. This would work in both cases for you.

 

-DP

--------------------------------------------------------

New Controls & Indicators made using vector graphics & animations? Click below for Pebbles UI


0 Kudos
Message 2 of 21
(4,339 Views)

I'm trying to avoid having to open and close the session in each function of the DLL, so I just want to pass the reference that's already open and only read and write in the DLL.

0 Kudos
Message 3 of 21
(4,329 Views)

In that case, why not use a "Functional Global Variable" to store session value that you can reuse within the DLL? That should work...


Seems like your issue is due to generation of reference value outside of LabVIEW, usually LabVIEW generates a unique reference number that is only valid within current instance.

 

-DP

 

--------------------------------------------------------

New Controls & Indicators made using vector graphics & animations? Click below for Pebbles UI


0 Kudos
Message 4 of 21
(4,325 Views)

This might not be entirely relevant, but I was able to pass a reference to a DAQ session by typecasting it to a string.

 

I had a collection of VIs which I built into a DLL as function calls.  One of them initialized an analog DAQ task, a different function call used that task to set a voltage, another function call closed the task, etc.

 

I typecast the DAQmx TaskID to a string and passed that between function calls.  It worked very nicely.

 

I don't know if you can do the same thing with a VISA session, but I'm thinking you can.


Hope that gives you a direction to go, at least?

0 Kudos
Message 5 of 21
(4,321 Views)

@BTC_Admin wrote:

In that case, why not use a "Functional Global Variable" to store session value that you can reuse within the DLL? That should work...


Seems like your issue is due to generation of reference value outside of LabVIEW, usually LabVIEW generates a unique reference number that is only valid within current instance.

 

-DP

 


But like I said, passing the reference works just fine. The problem is I have to do it different ways depending on whether the DLL is compiled from C or LabVIEW. I'd just like to know how to make it work for both.

0 Kudos
Message 6 of 21
(4,315 Views)

There are several issues here. First, a VISA Resource (or other string name resources in LabVIEW) are really a combination of a name and a session ID. If the session ID is invalid, LabVIEW will automatically open a session ID using the string name based on the refnum type. Obviously this won't work in a C function interface anymore as one does not have access to the low level C APIs in the LabVIEW kernel to treat the LVRefnum in such an dual mode way.

 

What does work is to pass the string to the first function as C String, and do an explicit VISA Open there, then return the VISA session to the caller as LVRefnum and treat it from there as such.

 

The LabVIEW Call Library Node does a few intrinsic conversions based on the configured datatype.

 

If you configure the parameter as String, LabVIEW will pass the resource name to the DLL function.

If you configure it as (U)Int32 (and in fact more precisely as pointer sized integer), LabVIEW will extract the underlaying ViSession from the VISA library and pass that one. You should use pointer sized integer instead of 32 bit integer, since a ViSession is really equivalent to a pointer and therefore would be 64 bit large in 64 bit LabVIEW.

If you configure the parameter to adapt to type, LabVIEW will pass its own VISA refnum to the function. This refnum is a LabVIEW intern entity, (and alwasy 32 bit in size and only valid inside the LabVIEW session who created it) and really wraps the ViSession into a LabVIEW refnum for internal bookkeeping reasons.

 

 

However the original post also shows TD1 errorIn and errorOut datatypes. This looks suspicially like an error cluster and that would be a thing that you can not easily create in non-LabVIEW land in a way, that LabVIEW will not crash when trying to access it.

Rolf Kalbermatter
My Blog
0 Kudos
Message 7 of 21
(4,302 Views)

So the LV built DLL expects the VISA session handle in another format than the C DLL. You have to figure out how LV passes the parameter. Play around with the prototype of the function exported by your C DLL. My first guess would be that the uintptr_t * VISAresource is an fact an uintptr_t ** . But maybe LV does something more exotic when adapting a VISA session.

0 Kudos
Message 8 of 21
(4,301 Views)

@Marc_A wrote:

@BTC_Admin wrote:

In that case, why not use a "Functional Global Variable" to store session value that you can reuse within the DLL? That should work...


Seems like your issue is due to generation of reference value outside of LabVIEW, usually LabVIEW generates a unique reference number that is only valid within current instance.

 

-DP

 


But like I said, passing the reference works just fine. The problem is I have to do it different ways depending on whether the DLL is compiled from C or LabVIEW. I'd just like to know how to make it work for both.



Have you tried typecasting inside your LabVIEW DLL?  (Assumption is that you're properly generating the reference in the first place, and not closing it until the end of your application needs.)

 

Untitled.png

--------------------------------------------------------

New Controls & Indicators made using vector graphics & animations? Click below for Pebbles UI


Message 9 of 21
(4,294 Views)

There is basically no easy way to make it such that LabVIEW can call both C DLLs and LabVIEW DLLs in such a way that the call parameter will work in both cases the same. A VISA ViSession is not the same as a LabVIEW VISA refnum. One is a VISA pointer sized entity that references a structure with maintenance information for VISA to know about what type of resource it is. The other is a LabVIEW i32 sized refnum that indexes a structure that contains the VISA resource name and the VISA ViSession. Conversion from LabVIEW VISA refnum to VISA ViSession is done at the Call Library Node when the parameter is configured as integer.

 

For LabVIEW VISA VIs to work one absolutely needs a valid VISA refnum or the resource name, so LabVIEW can open a VISA refnum to operate on. The only way I know of to get a VISA refnum is by using the implicit VISA open, when passing an unitialize VISA resource name to a function that operates on the VISA resource, or by explicitedly opening it with VISA open. Even if there would be a secret VISA session to VISA refnum node somewhere in LabVIEW it would require both the ViSession and the resource name to create a valid VISA refnum.

Rolf Kalbermatter
My Blog
0 Kudos
Message 10 of 21
(4,283 Views)