LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

how to set parameter Size of DSNewPtr for an array of double precision

 

I am trying to create a new pointer for an array of double precision elements using DSNewPtr. I am not sure what the parameter Size is.

 

I think it should be the number of elements in the array times 8 because each double precision number has 8 datatypes, but it doesn't work. Then I use the number of elements as the size for DSNewPtr, and it works. I don't understand why the size is the length of the array.

 

Thanks.

 

0 Kudos
Message 1 of 11
(3,817 Views)

I am a new labview learner, very confused about DSNewPtr and MoveBlock. I have been reading posts about them in this forum, but still not clear.

 

I tried a small example which was posted in this forum many years ago. The output of MoveBlock should be   values stored at the memory address, but this vi  creates address values.

 

Can anyone have a look and give me some advices please. Thank you.  

 

 

 

0 Kudos
Message 2 of 11
(3,758 Views)

Patient to doctor: Doctor it hurts if I press on this spot!

Doctor to patient: Then don't do it!

 

Why do you want to do this whole DSNewPtr() thing? This is not LabVIEW programming bit simply C programming, just on an even more complicated level. And you obviously do not have C programming experience. So it's not a good idea to try to build a moon rocket if you are still trying to build model cars.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 3 of 11
(3,734 Views)

Hi Rolfk, thank you very much for your reply!

 

You are right, I have zero experience of C programming, and I am also a new learner of LabVIEW.😂  The project that I am working on is about developing VI interfaces for C functions. 

 

Actually  the problem that I am stuck with is a returning pointer of pointer of 2D array (**data) from a DLL. After staying in this forum for a few weeks, I thought I might need DSNewPtr and Moveblock functions, that is why I am doing "research" on the two functions.

 

It is very lucky to get hold of you as I know you are an expert in LabVIEW. Can I take this opportunity to ask you how to deal with a returning pointer of pointer of 2D array (**Data) from a DLL?

 

My problem is very similar to this post  https://forums.ni.com/t5/LabVIEW/receive-array-pointer-from-dll/td-p/3290386?profile.language=en  The difference is that my output is **Data ( an array of pointers to 1D arrays), not *Data. You mentioned in this topic that " A 2D array could be an array of pointers to 1D arrays but more often is simply a single memory block with x * y data elements, so looks syntactically exactly the same as an 1D array buffer.", but you didn't say how to set an array of pointers to 1D arrays in the Call Library Function Node.

 

More clearly, the Data[ i ] points to the ith channel, the Data[i][1], Data[i][2],...., Data[i][n] are n data points in the ith channel. I need to display every data point for each channel in LabVIEW interface.

 

 

 

 

 

0 Kudos
Message 4 of 11
(3,724 Views)

Well for one, the example you mention is NOT about 2D arrays at all. It is simply about returning a normal array from the DLL. That's a huge difference and fully supported by the Call Library Node. You just have to make sure to manage the memory correctly as you have to do it too when calling such a function from C.

 

The only way to find out about if a 2D array is an array of pointers or rather a single memory block with x * y elements is usually to read the documentation and consult working C code examples that use that function. The syntax of the function prototype is usually not enough as the C syntax is not meant to cover such "details".

C is designed as a programming language that sits pretty close to the bare metal of the CPU and many things in C are left open to the implementer of a particular compiler for a specific CPU. As far as datatypes go, it only defines basic elements such as pointers, integers and floating point datatypes and the two compound types array and struct but even arrays are in fact only pointers. There is a special syntax for arrays, but it is mostly just syntactic sugar coating and has no practical meaning, with the exception for fixed size arrays.

 

So to create your array of pointers you basically do exactly the same as you would do in C, and not knowing C means that you basically miss the fundamental basics to even comprehend how this should work.

 

Here is one example that I recently posted here on this forum that uses arrays of pointers and you can take a look at that. It is NOT exactly the solution you look for but shows the principle about creating an array of pointers in LabVIEW and copy out the data from them (although it's for a string here) after the Call Library Node call (and properly deallocating them afterwards). However without the proper understanding of C programming with respect to pointers, you may be able to create something that seems to work, but most likely will create a memory leak generator or a memory corruption engine or even both!

 

The basic rule about the Call Library Node is: If you can't write the code to call a specific function in C, you should not try to write a LabVIEW VI to call that function! This is by far not enough to make sure the resulting VI code won't corrupt memory, crash your program or eat your sandwich, but it is a fundamental prerequest.

 

From a quick glance at your original VI there are several obvious errors.

 

1) You write that a double is 8 byte and the according array pointer therefore should be 8 times the number of array elements but you only use 1 as multiplicator. Your mentioning that it only works when you use 1 as mulitplicator makes no sense because of the following point.

2) The MoveBlock function does nothing useful as it is now. It basically copies the random memory content from the newly created memory block into your double array. The returned data intepreted as double values is still garbage, just as the bytes in the allocated memory block are.

 

As far as your second VI is concerned it has similar problems:

 

1) You allocate a memory block of 8 bytes => Good

2) You copy the content from that memory block into the passed in LabVIEW array! => WTF

3) You copy the content from that memory block into the newly created array. => Fine, but the array is 4 elements long while you only use two of them both in the MoveBlock() function and later on. Because of the f*ck up in stage 2) you won't get any different data than the original random data from the memory block!

4) You dispose the pointer. => Very Good

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 5 of 11
(3,697 Views)

Hi Rolfk, thank you very much for the information.

 

I have better understanding of DSNewPtr and MoveBlock functions now.

 

Following the format of the given example, I managed to create the diagram for my case: create an array of pointer (DSNewPtr) --> input it to my call function-->copy each array out to a 1D array (MoveBlock)--> finally get a 2D array.

 

For the setting of the returning **Data from my call function node, I used

Type: Array

Datatype: unsigned pointer-sized Integer

Dimensions:1

Array format: Array Data Pointer.

 

When I run my VI, sometimes it works, sometimes it crashes, just like you said in your last post. You are very visionary! Could you please give me further advices on how to make it work properly.

 

Thank you!

0 Kudos
Message 6 of 11
(3,685 Views)

Just realised that the file was not uploaded succssfully in my last post.

0 Kudos
Message 7 of 11
(3,673 Views)

As I already told you, there is no easy way to see what implementation a 2D array is using in C without seeing the source code of the function itself or some exemple code which call the function and is fully proven to be correct!

 

As you haven't shared any of these (and not even the original function prototype) the only reason I provided that link with the array of pointers was because of your claim in your initial mail that you needed that. I have no way of verifying that that is really the case as I do not have any of these things available. 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 8 of 11
(3,655 Views)

Hi Rolfk

 

I have attached some example code which call the function, and it has been proven to be correct.  Its function prototype is also included in the attached file.

 

Please let me know if more details are needed.

 

I really appreciate your help.

 

 

0 Kudos
Message 9 of 11
(3,635 Views)

Well, ok! It does indeed require an array of pointers. But your claim that it is fully tested and error free is not quite right. The example code as is will create a memory leak of 8 * 8 * xres * yres bytes. For this example it doesn't matter as it is just a main() function and the memory will be released at the termination of the process anyways, so nothing bad happening, but for example code still not that great.

 

Your posted VI has a few (potential) problems too:

 

- The number of points for each channel needs to be of course xres * yres, not an arbitrary 10000 samples.

- You create 8 channels but only read 2 after the function call. This might be valid as the other channels might not contain interesting (or useful) data, but you need to be aware of that.

- More serious though you allocate 8 memory pointers but only deallocate the first 2! Nice memory leak with every call of that function. Just remove the constant to the N terminal completely. You ALWAYS want to deallocate ALL pointers you initially created.

 

But there are still several open questions. One is that the VI you posted is NOT calling this DLL function. There are other parameters to this function that need to be configured right and passed in with valid data to get any meaningful result. Do you do that?

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 10 of 11
(3,605 Views)