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 an Array of Clusters from LabVIEW to a DLL.

Solved!
Go to solution

 


@Britoa wrote:

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


Actually it is still not useless. Consider this code:

 

char* myPtr = NULL;

 

 

void resizeme(char** data)

{

    *data = realloc(*data, 5000);

}

 

void dosomething(char* data)

{

       data[0] = 0;

}

 

main ()

{

     char *ptr = malloc(2000);

 

     myPtr = ptr;

 

     resizeme(&ptr);

 

     dosomething(myPtr);

}

 

 

dosomething() will cause a protection fault as it most likely will try to access a pointer which has been invalidated by realloc.

 

This is of course easily circumvented in this trivial example but consider software that holds onto data pointers for instance in the user interface to be able to redraw something while these data pointers may have to be resized during operation. Aside from the synchronization issue you have to solve as well anyways, this simply can't work as a pointer will often be invalidated by a realloc. And having the software to inform all possible users of a pointer that it has been changed is a complete nightmare to manage. Instead using handles various parts can hold onto that handle and even resize it and all the other references to that handle stay still valid. You need to use semaphores to prevent two different parts of the software accessing the data handle at the same time but you do not need to put a mechanisme in place to message all possible clients about a change of the data handle.

 

Of course in modern software this is solved with objects and OO programming but that is in fact just a glorified handle on steroids. Instead of only a pointer holding a reference to the data buffer and information about its size, it is a pointer that can and usually does contain one or more references to dispatch tables with methods to operate on the data.

 

 

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 31 of 43
(2,177 Views)

Sorry thought prototype of PassThruIoctl function is enough so i did not posted the documentation for the PassThruIoctl function.

 

I understood about CIN.

prototype is for AZNewPtr is 

UPtr AZNewPtr(size);

How to configure return type UPtr for this?

0 Kudos
Message 32 of 43
(2,163 Views)

What about using Pointer sized integer? Sorry for being brief but you seem to think we can mind read your program and provide minimum information.

Rolf Kalbermatter
My Blog
0 Kudos
Message 33 of 43
(2,160 Views)

I am using Call library function to implememnt this by giving labview.exe as library.

I am using AZNewPtr,AZNewPtr,AZDisposePtr functions to take block of memory and copy the data.

I have given 8*NumOfParams for size(Each Parameter hold 4bytes and param values holds 4 bytes value =8 bytes).

 

When dll is called for PassThruIoctl function labview crashes.

 

Actualy i dont see any difference in the previous implementation and this ,both time its taking pointer to value.

 

Please suggest me i am doing anything wrong in this implementation.

 

Find the VI attached here.

0 Kudos
Message 34 of 43
(2,141 Views)

Think about dataflow!

 

What is preventing AZDisposePtr from executing before MoveBlock and PassThruIoctl is executed? The fact that it is on the most right function in the diagram? If you believe so think again and study LabVIEW dataflow principle a bit more.

 

Also are you sure you need to specify the bytes that are in the pointer (so using the multpily by 😎 or the number of records?

Rolf Kalbermatter
My Blog
0 Kudos
Message 35 of 43
(2,136 Views)

See related post here, which FINALLY includes the actual header file.

 

The FiveBaudInit call referenced in the other thread should look something like this:

 

LVPassThruIoctl.PNG

 

Be careful about pointers!  The output of DSNewPtr, while actually a pointer, needs to be passed as a value to functions that expect a pointer, such as MoveBlock.

0 Kudos
Message 36 of 43
(2,106 Views)

Thank you.This works for me.

But in the response I am getting the pointer value agian not the actual value.

Response for the FiveBaudInit is 2 bytes of data 0x08 0x08.But i am getting addresses of that array.

Find the attached VI.

0 Kudos
Message 37 of 43
(2,087 Views)

@22445466 wrote:

But in the response I am getting the pointer value agian not the actual value.

Response for the FiveBaudInit is 2 bytes of data 0x08 0x08.But i am getting addresses of that array.


Are you certain that you're getting the address of the array?  You might just be getting garbage data because you used the wrong data type.  You allocate an array of U32 values but then pass that to MoveBlock by reference as an array of U8.  So you're actually copying two bytes of data into a single 32-bit value, instead of copying into two U8 values.  Change the numeric representation in initialize array (and the output cluster).

 

It is a good idea to chain the error wires together as I did in my example; it ensures that the function calls occur in the order you expect and simplifies error handling.

 

I hope that this gives you enough information to get your other functions working as well.

0 Kudos
Message 38 of 43
(2,075 Views)

Yes it looks like i am getting garbage data.

But as you said i have changed data type but still its not working.

Find the attached VI.

 

I dont know how chain the error wires,i just tried here i think its not correct.

But I have wired DLL call function error code.

 

0 Kudos
Message 39 of 43
(2,062 Views)

By "chain the error wires" I mean connect the error out terminal of each Call Library Function Node to the error in terminal of the next one, so that each function executes in order and only if the previous one did not generate an error.  Running a long error wire behind all those function calls without connecting it to any of them isn't useful.

 

I don't know what's wrong at this point.  Are you certain of the data you should get back?  (And if you already know what data to expect, why would you need to call that function?)  Wire the error in/out as I suggested above and see if there is an error at the final error out terminal; if so, post that error information.  You could call DSNewPClr in place of DSNewPtr (parameters are the same, just change the function name), which clears the allocated memory.  Then, if you get any data in the output cluster, you'll know that that data was filled in by the Ioctl call.

 

Next time you post a VI, take a few minutes to clean it up (straighten the wires, keep things neat) before you post it.  It's hard to read your VIs when the wires take unnecessary bends and overlap with each other.

0 Kudos
Message 40 of 43
(2,057 Views)