LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

array pointer from dll

 


@f. Schubert wrote:

There are some hidden functions inside the LabVIEW.exe and the lvrt.dll that allow you to mess around with pointers. In the CNL, type in LabVIEW, this automatically redirects you to the lvrt.dll when you build an application. These functions are completly undocumented, but ther is a header file (search for LabVIEW.h and lvrt.h).


Actually these functions are documented in the External Code Reference Manual which is part of the online documentation that is installed with LabVIEW. There are indeed more function that are undocumented but for all practical work they are useless for 99.9% of the LabVIEW users.

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 21 of 36
(2,233 Views)

Josh

Sorry for a late response.I am implementing the WdfGetScaleWave function into a scalable LV array. I understand you got help with the Yoko WDF files. Is the DLL performing for you satisfactorily? I am reading from SL1000 recorders. I need to be somewhat careful with disclosure, but I would like to see if I can help keep you moving.

Jim Henderson

jim.henderson@sce.com

0 Kudos
Message 22 of 36
(2,220 Views)

Jim,

 

Thanks for your response.  I did get what I needed through another post (go to the end of page 2 for the link).  I was making some mistakes with datatypes and also needed to add a "pad to line up the data elements" within the cluster.  Not being a programmer or having a programmer in-house, I never would have gotten that without the forums.  I am now able to get the scaled data into labview straight from the .wdf file.  Now I can move forward with writing custom analysis routines we can use that are not available with the xViewer software.

 

Regards,

Josh

0 Kudos
Message 23 of 36
(2,218 Views)

Hey Forum,

 

I've been looking over what you guys have here and I have a very similar problem.  I'm on the verge of figuring this out and I'm hoping my programmer community can lend a hand.

 

I have a .dll (NicOem_read.dll) that I'm referencing in LabView with a call library function node.  The function being called is NicOem_read which is basically reading data from an external device and bringing it to the onboard memory of the computer. The prototype for the function, from the manufacturer, is as follows:

 

NicOem_read (void* srvhnd, void* fd, void* buf, int bufbytesz)

 

srvdnd and fd are two 32-bit integers that are generated using other functions within the .dll, and I have no problem with those.

 

The variable buf needs to be a 32-bit memory address of location to read device data into, this location needs to be bufbytesz bytes.

 

So basically, I need to allocate memory of bufbytesz bytes, get the address of that memory, and pass those to variables to my read function.  Once the data has been read to the computers memory, I'll need to read it from that location and either put it into an array and write it to a file, or just directly write it to a file.

 

I've attached the code that I have so far, and it just hangs up LabVIEW to the point where I have to force close it.

 

Any help/advice would be greatly appreciated, THANKS FORUM!!

 

Adam

Download All
0 Kudos
Message 24 of 36
(2,067 Views)

It would help if you could backsave the VIs to at least 2011 before uploading them.

 

Most likely what you want to do is allocated a Byte Array in LabVIEW (with Initialize Array) and pass the size of that array in the last parameter. Configure the parameter in the CLN as Array Data Pointer.

Rolf Kalbermatter
My Blog
0 Kudos
Message 25 of 36
(2,061 Views)

As requested, a later version of the VI.

 

Adam

0 Kudos
Message 26 of 36
(2,056 Views)

You need to sort out your data types, as well as which items are pointers and which are values. Do you have any background in C programming? If not, the distinction between pointers and values may not make much sense.

 

When you call nicOem_read, you need to pass buf by VALUE, not as a pointer to value. It's just like the other two pointer parameters, srvhnd and fd. DsNewPtr returns a value that is actually a memory address, ie a pointer. If you pass it by pointer, the DLL call gets a pointer to the address where the pointer is stored, rather than a pointer to the memory you actually allocated. This will likely cause a crash when the DLL writes to the wrong memory location. Same thing goes for the MoveBlock call - buf needs to be passed by value.

 

You need to sort out your datatypes as well. Why are you allocating an array of doubles, then passing it as an array of pointer-sized ints with the array size set to bufbytesz, when that doesn't even match the number of bytes you want to move?

 

EDIT: also, when asked to backsave a VI, that means save as an earlier version, not upload a second copy in the same version that you already provided.

Message 27 of 36
(2,048 Views)

Nathand,

 

Thank you for all of your help.  I am somewhat novice when it comes to C programming.  I don't have any experience with pointers or referencing memory, this is the first time I've been exposed to it, so it's been a steep learning curve.

 

I have my third party .dll running now but the DSDisposePtr is throwing a 1097 error and I can't seem to figure out what's going on.  It has an error message but I can't configure the CLN to return anything, it's just not working.  I've attached the working VI.  Any idea why it isn't working.

 

Thanks again for your help. The VI is saved as LV 8.6.

0 Kudos
Message 28 of 36
(2,027 Views)

Sometimes it's a good idea to back up and look at the goal, rather than the method being used to get there. You don't need any of the CIN functions (DsNewPtr,MoveBlock,DsDisposePtr). All you need to do is initialize an array and pass it to your DLL. No need to make it so complicated.

 

However, you do NEED to get your data types straight. The bufbytesz appears to be the number of BYTES in the buffer (the array you initialize). If you create an array of U32, then each element is 4 bytes, and the value passed as bufbytesz should be 4x the number of elements. When you configure the Call Library function to pass an array, there's a "minimum size" parameter for arrays - that's the number of elements in the array (NOT the number of bytes). You should leave that parameter set to none, because otherwise you will have a mismatch between the array size and the number of bytes.

 

The reason for using the CIN functions is when a pointer is part of a larger structure, and that's not the case here.

Message 29 of 36
(2,019 Views)

What Nathan is pointing out was what I was already trying to tell you earlier. If the array is a function parameter there is really no need at all for pointer acrobatic on your side. LabVIEW's Call Library Node allows for enough flexibility to handle this all for you and even much more performent as there will be no unneccessary copies at all.

 

Look at this VI in the attachement, it does everything your VI was meant to do, as far as I could determine, didn't check every detail, but without an extra data copy by the MoveBlock function. If everything is right with the dimension calculation and all I'm not really sure. Especially I find it suspect that you multiply the Points per trace by 2 but use I32 elements. and I32 is 4 bytes and this calculation definitely will be wrong if the last parameter to the DLL function is really in bytes. So check out that calculation some more!!!

 

Also note that I changed the first two parameters to be pointer sized integers. If you configure them as 32 bit integers this only will ever work in LabVIEW for Windows 32 Bit.

Rolf Kalbermatter
My Blog
Message 30 of 36
(2,008 Views)