LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Fun With Passing Void Pointers

(This is actually in regards to http://forums.ni.com/ni/board/message?board.id=170&message.id=277290 , but I think I can phrase my problem more elegantly now.)

I have a C DLL which requires a void pointer to be passed to it.  Specifically, the pointer has to point to a preallocated block of memory, into which will go a known number of 16-bit integers.  The memory block then gets filled by a separate function call.

I have thus configured a Call Library Function Node to pass an array of 16-bit integers in the format of an Array Data Pointer.  By specifying a minimum size, I can ensure that sufficient memory is allocated.

Unfortunately, the first two elements of the array that gets returned appear to each contain half of a 32-bit integer which I assume is a pointer to the block of memory.  I'm thinking I could reconstruct the integer and then use MoveBlock (as in http://zone.ni.com/devzone/cda/epd/p/id/2242) to access the block of memory, but I can't help but think that I'm going about this entirely the wrong way - especially since LabVIEW tends to become unstable whenever I run the VI, usually crashing soon afterwards.

Does this make sense to anyone?  What is the right way to do this?  I suppose I could pass a single 32-bit integer (i.e. a memory address) instead of the array, but then how will I allocate the memory at that address?
0 Kudos
Message 1 of 13
(3,848 Views)
Have you taken a look at the "Call DLL" example that ships with LabVIEW? That shows you how to interface to C using a wide variety of data types, including arrays. Open up the Example Finder (Help->Find Examples), switch to the Search tab, and enter "DLL" for the search string.
0 Kudos
Message 2 of 13
(3,844 Views)
Yes, I've seen that, but I'm not sure how it applies.  I need to access the same block of memory sometime _after_ using the Call Library Function Node, rather than using the node's output directly.  At least, I think I do.

Maybe there's some way I can get the 32-bit address of an array I've allocated in LabVIEW?
0 Kudos
Message 3 of 13
(3,835 Views)
I not sure I followed you entirely. Do you need the pointer to the array, or the actual array values? If all you want is to pass the pointer from one dll call into another dll call, you can use the I32. If you want to use the data in labview, then is sounds like your call library node may not be configured correctly. It is definitely possible to get the array values out; I do this all the time.

I think you are getting instability because you are writing to memory that was not really allocated, thus overwriting something else.

I may not have the right vocabulary (I'm really a LabVIEW guy and not a C guy), but wouldn't a void pointer be empty or null? I guess if the pointer is really pointing to a block of memory that has been preallocated by LabVIEW, I wouldn't call it void. The way I usually do this is dynamically allocate an array of appropriate size using initialize array and pass that into the Call Library Node for the argument that is an array pointer. On the other side of the node, the array will come out with data in it.

Chris
0 Kudos
Message 4 of 13
(3,820 Views)
I get the impression that a void pointer is used (at least in this case) if a C function needs to be able to work with a variety of different data types.  (That is, the function might need to fill the memory block with unsigned 16-bit integers, or signed 32-bit integers, etc.)

Let me rephrase this: there is one function call that requires the void pointer.  However, the function only starts data acquisition - the array is still empty as soon as the function returns.  (In fact, I have another function call that I can use to monitor the acquisition and let me know when it is finished.)  Thus, if I wire the output terminal of the function node to something else, LabVIEW will just make a copy of an empty array, right?  The way I see it, the only way to access the memory location of that array afterwards (when it is no longer empty) is to somehow use the pointer.

Right now I'm looking at the other LabVIEW Memory Manager functions (namely DSNewPtr), but I'm still only causing crashes at this point...

Message Edited by kehander on 10-11-2007 11:11 AM

0 Kudos
Message 5 of 13
(3,807 Views)
Hey, wait, I think I got it!  And it's not even crashing!  (I was allocating the wrong number of bytes with DSNewPtr.)

Still, if there's a more elegant way of doing this, I'd like to hear about it.
0 Kudos
Message 6 of 13
(3,800 Views)
i don't really think you need to mess around with DSNewPtr. I would suggest reading this thread in detail. It sounds almost exactly like what you're trying to do.
0 Kudos
Message 7 of 13
(3,780 Views)
Okay, I had to do a little research because I was not familiar with the LabVIEW Memory Manager functions (I don't write in C). This is all making more sense now. It looks like a Void Pointer isn't empty, it's just a pointer to a block of memory that has not had its type defined. It doesn't seem that different than allocating a block of memory by initializing an array of U8's of specified length. In either case, you would just typecast the data at the block of memory to the type that you want when you read it. [some C person should feel perfectly free to jump in and correct me if I am munging this up].

Anyway, it sounds like your acquisition Start function needs a void pointer (of what length?) when it is called. Then you need to pass that same pointer to the another function (the read function?) when you want to get data back. I guess the way that I would have handled this (and granted, I didn't know about LVMM functions) would have been to allocate an array of the correct size of I16s in LabVIEW and pass it into the first call library node (CLN). The function gets a pointer to a block of memory of the correct length. Then the array comes back out of the CLN, still all zeros or whatever. Pass this array into the next CLN, and it would come out with values in it. LabVIEW will not copy the data at that block unless you do something like branch the wire. It's not really clear to me that the function would care if it received a different pointer to a block of memory of the same size anyway.

Anyway, hopefully this helps a bit.
Chris
0 Kudos
Message 8 of 13
(3,772 Views)
Well, the key thing is, there is no second node.  Once the acquisition is complete I just need to process the array further in LabVIEW.  This makes the situation slightly different from that described in the thread linked to by Mr. smercurio_fc .

Still, if I understand correctly, I should be able to put my CLN and the call to the monitoring function inside a subVI, and the array that is subsequently output by the subVI when the acquisition is complete will contain the values.  That certainly does sound more elegant (or should I say "spooky" ? Smiley Wink ).
0 Kudos
Message 9 of 13
(3,766 Views)

Hello Kehander,

Were you able to find an elegant way of retreiving the array from the memory address? Even if not, could you please attach your example in how you were able to get the array from the memory?

Thanks,

Omer

0 Kudos
Message 10 of 13
(3,399 Views)