LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Passing an Array of Clusters from LabVIEW to a DLL.

Solved!
Go to solution

Do you understand what you are doing here, and do you have any experience with C pointers and data types?  If not, you will probably crash LabVIEW and have trouble getting this right.  Why are you generating clusters of 129 elements?  Where you have a NaN value, are you trying to pass a null pointer?  If you don't understand why the previous solution works, and why this one does not, then you will want to learn more about C programming before continuing with this project.

 

In order to get this function call right you will need to use the LabVIEW memory manager functions to get a pointer that you can bundle into a cluster.  Can you post the .h file that comes with your DLL, and any supporting documentation for this function?  I am surprised that the function prototype has void * types; it would be helpful to see an explanation of what those parameters are supposed to contain.  I expect that the .h file will also contain a definition of J2534_IOCTLPARAMID.

0 Kudos
Message 21 of 43
(1,771 Views)

this one is actually much easier than the other one...

 

Make a cluster with a u32 (with the value of the number of params) and an array of sconfig clusters. 

 

I know labview will automatically make the array of sconfigs into a pointer to an array of sconfigs, I do not know if it will make it an array of pointers, though (that's a tougher question)

0 Kudos
Message 22 of 43
(1,769 Views)

@Britoa wrote:

this one is actually much easier than the other one...

 

Make a cluster with a u32 (with the value of the number of params) and an array of sconfig clusters. 

 

I know labview will automatically make the array of sconfigs into a pointer to an array of sconfigs, I do not know if it will make it an array of pointers, though (that's a tougher question)


Sorry, but this is incorrect.  When you put an array into a cluster and pass that to a DLL, LabVIEW will NOT make the array into a pointer to the array.  Instead it will provide a HANDLE to the array (per the Call Library Function Node help).  If the DLL does not know what to do with a LabVIEW handle (any DLL not written specifically for LabVIEW) then it will not work.  The way to set this up is to call DSNewPtr to get a block of memory, use MoveBlock to copy the data into that memory area, then bundle the pointer into a cluster along with the U32 number of params.  After the DLL call completes, use DSDisposePtr to release the pointer.  This is definitely NOT easier than the previous one since it cannot be handled without calls to internal LabVIEW functions.

Message 23 of 43
(1,768 Views)

really?  I mean... what the... someone was smoking something good when they decided that one...

*doesn't see a use for LVHandles outside of LV... ever*

 

half the time they say handle in the help when relating to dll, it says it's a pointer the next line, so I made the assumption.  ouch.

(Learned something new at 7:20am, my day is done early today!)

0 Kudos
Message 24 of 43
(1,756 Views)

J2534_IOCTLPARAMID is enum variable having some set of ioctl id's.

Did you meant using CIN to implement this.Calling code from text based programming langauages.

 

Yes i want to send null pointer to another parameter pOutput.Since its not used.

 

See the attached VI.

 

I have changed cluster to array of U32 but still its sending pointers.DLL not getting the value its getting address.

 

 

0 Kudos
Message 25 of 43
(1,754 Views)

Here one more vi which will read messages coming from the bus.

PassThruReadMsgs

(unsigned long ulChannelID,

  PASSTHRU_MSG  *pMsg,

  unsigned long *pulNumMsgs,

  unsigned long ulTimeout);

 

typedef struct

{unsigned long ulProtocolID;

unsigned long ulRxStatus;

unsigned long ulTxFlags;

unsigned long ulTimeStamp;

unsigned long ulDataSize;

unsigned long ulExtraDataIndex;

unsigned char ucData[PASSTHRU_MSG_DATA_SIZE];

}PASSTHRU_MSG;

 

Same as PasstrhuWriteMsg.

See the attached vi.Its not working.

And i have to run this vi conitinuously since have to collect all incoming messages.So i need to run this vi continuosly like thread.

Please suggest me how to do this.

 

0 Kudos
Message 26 of 43
(1,749 Views)

@Britoa wrote:

really?  I mean... what the... someone was smoking something good when they decided that one...

*doesn't see a use for LVHandles outside of LV... ever*


Nobody smoked something. LabVIEW was first developed on MacOS for CPU. There you hadn't the same virtual memory management unit in hardware as computers have nowadays. Allocated memory blocks were not movable nor resizable on the fly. So Apple devised memory handles which allowed to reallocate the memory buffer without invalidating the original handle. LabVIEW as a highly dynamically allocated application had to use that same principle. But when porting it to Windows they couldn't just change everything if they wanted to stay compatible and in fact the Windows 3.1 memory management was not much better than on MacOS so it helped there too. The first platform that wouldn't have needed this implementation anymore was Sun Solaris and Windows NT, but by that time LabVIEW had gone into version 4 and 5 and changing this was absolutely no option anymore as to much customer code (and especially CINs, the predecessor of the Call Library Node where relying on that exact memory layout.

Rolf Kalbermatter
My Blog
0 Kudos
Message 27 of 43
(1,740 Views)

@Britoa wrote:

really?  I mean... what the... someone was smoking something good when they decided that one...

*doesn't see a use for LVHandles outside of LV... ever*


Nobody smoked something. LabVIEW was first developed on MacOS for 68k CPU. There you hadn't the same virtual memory management unit in hardware as computers have nowadays. Allocated memory blocks were not movable nor resizable on the fly. So Apple devised memory handles which allowed to reallocate the memory buffer without invalidating the original handle. LabVIEW as a highly dynamically allocated application had to use that same principle. But when porting it to Windows they couldn't just change everything if they wanted to stay compatible and in fact the Windows 3.1 memory management was not much better than on MacOS so it helped there too. The first platform that wouldn't have needed this implementation anymore was Sun Solaris and Windows NT, but by that time LabVIEW had gone into version 4 and 5 and changing this was absolutely no option anymore as to much customer code (and especially CINs, the predecessor of the Call Library Node where relying on that exact memory layout.

Rolf Kalbermatter
My Blog
0 Kudos
Message 28 of 43
(1,739 Views)

@22445466 wrote:

J2534_IOCTLPARAMID is enum variable having some set of ioctl id's.

Did you meant using CIN to implement this.Calling code from text based programming langauages.

 

Yes i want to send null pointer to another parameter pOutput.Since its not used.

 

See the attached VI.

 

I have changed cluster to array of U32 but still its sending pointers.DLL not getting the value its getting address.


I'm suggesting that you need to use some of the functions that are documented for use in CINs, however you can call those functions directly from LabVIEW by setting up a Call Library Function Node with the library name set to "LabVIEW."  The functions you will need are DSNewPtr, MoveBlock, and DSDisposePtr.  I do not think there is any way to do this in LabVIEW without resorting to the use of those functions.  Also, a null pointer is the value 0.  It is not NaN, and it is not a pointer to NaN.

 

Is this the function you're trying to call: http://www.drewtech.com/support/j2534/PassThruIoctl.html ?  It is the first Google search result for "PassThruIoctl."  If you can't be bothered to do a quick web search and post a link when asked for documentation, why should anyone help you?

 

You NEED to know something about memory allocation, in both C and LabVIEW, before you can make these function calls work properly.  It's not worth my time to help you if you can't understand what the code is doing.  If your goal is simply to get it working as fast as possible, pay someone to do it for you.

 

For PassThruReadMsgs, you need to pre-allocate enough space not just for one message, but for as many messages as you plan to read.  You will probably find it helpful to typecast the data back to an array of the same large cluster after the DLL call so that you can get at the data more easily.  You will also need to word- and byte-swap it.  Yet again, Adapt to Type is the wrong way to set up the pmsg parameter.  Pass it as an array, by array data pointer.

0 Kudos
Message 29 of 43
(1,732 Views)

Thanks for the history lesson, it just seems useless for today, but for the sake of backwards compatibility, I get it (and accept it)

0 Kudos
Message 30 of 43
(1,724 Views)