LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

call library function node: malloc to recieve a struct

normally when a CLFN returns a pointer to a STRUCT, I build a cluster on the diagram of the proper data types, wire it to the input terminal of the node, and configure the parameter to "Adapt to type" and Handles by Value; and the cluster indicator (output) returns the STRUCT.
In this particular case I am getting an Invalid Buffer error and I believe it has something to do with malloc (insufficient memory allocation?).
The function proto-type is:
S16BIT DECL aceMTIGetCh10DataPkt(S16BITDevNum, CH10_DATA_PKT *ppCh10Pkt, S16BIT Timeout)
- where ppCh10Pkt is a  "Pointer to an IRIG Chapter 10 Data Packet Pointer"
 
The C-code usage is as follows:
S16BIT DevNum = 0;
S16BIT wResult = 0;
CH10_DATA_PKT*  pPkt = (CH10_DATA_PKT*) malloc(0x20000)
 
wResult = aceMTIGetCh10DataPkt (DevNum, &pPkt, -1);
 
It seems that wiring the cluster to the input to allocate memory for the returned cluster is insufficient, somehow I need to allocate by a factor of 128K(?). Can anybody clarify this?
 
thanx in advance
lmd2
Lawrence M. David Jr.
Certified LabVIEW Architect
cell: 516.819.9711
http://www.aleconsultants.com
larry@aleconsultants.com
0 Kudos
Message 1 of 50
(5,025 Views)
Lawrence,

Is the DLL or LabVIEW throwing the malloc error?

Have you turned on maximum error checking with your CLFN?

Assuming your malloc for 0x20000 is your 128k, are you able to increase this 1.5 or 2 times?

In your DLL when are you destroying your memory allocation?

Lastly, I am curious as to why you are needing to allocate memory with the pointer - shouldn't the pointer already be referencing something pre-loaded into memory?
Regards,

Jared Boothe
Staff Hardware Engineer
National Instruments
0 Kudos
Message 2 of 50
(5,001 Views)
sorry, let me elaborate; the client has requested the driver by in LabVIEW 7.0
so error checking is minimal
the problem is that I don't know the LabVIEW version of malloc, memory allocation is done dynamically in the background, so how would I increase it by 1.5 or 2X?
the allocation is for a buffer which is filled if messages are present on the bus

thanx
lmd2
Lawrence M. David Jr.
Certified LabVIEW Architect
cell: 516.819.9711
http://www.aleconsultants.com
larry@aleconsultants.com
0 Kudos
Message 3 of 50
(4,997 Views)


@lmd2 wrote:
sorry, let me elaborate; the client has requested the driver by in LabVIEW 7.0
so error checking is minimal
the problem is that I don't know the LabVIEW version of malloc, memory allocation is done dynamically in the background, so how would I increase it by 1.5 or 2X?
the allocation is for a buffer which is filled if messages are present on the bus

thanx
lmd2

When you create an array or string or any variable on a diagram LabVIEW is behind the scenes mallocing the memory for you automaticially and when you pass such a wire to the Call Library Node it's memory address is passed to the DLL according to that parameter configuration. So unless your C function does want to resize, deallocate or otherwise change that memory pointer itself there is no need to know about what malloc was used.

Your problem is a different one I guess. While the parameter looks like a pointer to a structure it is apparently a pointer to an array of structures. In C these two things are exactly the same as far as the compiler is concerned. It is only the context of the function and it's callers that determine if it is one or the other.

Now the problem is that you cannot pass an array of clusters to a DLL function directly since the necessary translation of that could get rather complicated and it's configuration would cause the Call Library Node Dialog to get complicated beyond anyones imagination and consequently beyond most peoples comprehension and usability.

So if you need to do this all in LabVIEW instead of writing a wrapper DLL you will have to allocate an array of Bytes instead with the Initialize Array function and pass that like that to the DLL function. On return and if you would be in LabVIEW 8.2 and better you might be able to Unflatten the Array of Bytes into an Array of Clusters if this cluster does not contain any arrays or strings and specify to use Little Endian format and data includes array or string size = False.

However LabVIEW 7 does not have such a versatile Unflatten. You might be able to use Typecast instead but will have to pass the resulting array of cluster wire through the swap bytes and swap words function too in order to compensate for the Big Endian standardization that is done by the Typecast function.

Rolf Kalbermatter
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 4 of 50
(4,979 Views)
Thank you
this sounds correct, although implementing it is going to take a bit of doing (actually the cluster does contain two arrays of U16, but no strings (arrays of U8)). Normally I can handle an array within a cluster by converting it to a cluster within a cluster - but in this case, this will make it more difficult to do a type cast.
But you have given me some insight and a direction -
thanx again,
lmd2
Lawrence M. David Jr.
Certified LabVIEW Architect
cell: 516.819.9711
http://www.aleconsultants.com
larry@aleconsultants.com
0 Kudos
Message 5 of 50
(4,975 Views)


@lmd2 wrote:
Thank you
this sounds correct, although implementing it is going to take a bit of doing (actually the cluster does contain two arrays of U16, but no strings (arrays of U8)). Normally I can handle an array within a cluster by converting it to a cluster within a cluster - but in this case, this will make it more difficult to do a type cast.
But you have given me some insight and a direction -
thanx again,
lmd2

Well it all depends on if this array is fixed size (unsigned short name[x]) or if it is just a pointer (unsigned short *name). In the first case the C compiler inlines the array and you can indeed treat it as an embedded cluster of the right (x) amount of elements, but in the second case you have to treat it as an uInt32 (uInt64 on the upcoming LabVIEW for Windows x64 platform) and do some other magic if you need to retrieve the values.

Inlined clusters in a cluster are no problem for the Typecast function. Pointers treated as unsigned integer also not.

Rolf Kalbermatter


Message Edited by rolfk on 06-20-2008 11:08 AM
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 6 of 50
(4,971 Views)
Thanks Rolf
yes both arrays are of fixed length
I should be OK now

Have a great day

lmd2
Lawrence M. David Jr.
Certified LabVIEW Architect
cell: 516.819.9711
http://www.aleconsultants.com
larry@aleconsultants.com
0 Kudos
Message 7 of 50
(4,960 Views)

Rolf

In LabVIEW 7 when I configure the CLFN, even though I am sending in an array of bytes (U8) to allocate space, I will config the parameter not as an array, but adapt to type (I think) or should it be configured as an array? If 'adapt to type' then the data format would be either HANDLES BY VALUE or POINTERS TO HANDLES  -  I am thinking POINTERS TO HANDLES

On the other hand, if the parameter should be configured as an array of bytes, which of the three array formats should I use?

 

thanx

lmd2

Lawrence M. David Jr.
Certified LabVIEW Architect
cell: 516.819.9711
http://www.aleconsultants.com
larry@aleconsultants.com
0 Kudos
Message 8 of 50
(4,916 Views)
ok, adapt to type (any data format) crashes Windows - blue screen of death!!
Array also crashes if data format is array handle, or array handle pointer
the only thing that doesn't crash windows is Array / array data pointer - which returns an error of "invalid buffer"
since this is the only config that doesn't crash LV & WindowsXP I will try and get this config working
 
I am open to suggestions ...
Lawrence M. David Jr.
Certified LabVIEW Architect
cell: 516.819.9711
http://www.aleconsultants.com
larry@aleconsultants.com
0 Kudos
Message 9 of 50
(4,907 Views)


@lmd2 wrote:
ok, adapt to type (any data format) crashes Windows - blue screen of death!!
Array also crashes if data format is array handle, or array handle pointer
the only thing that doesn't crash windows is Array / array data pointer - which returns an error of "invalid buffer"
since this is the only config that doesn't crash LV & WindowsXP I will try and get this config working
 
I am open to suggestions ...


Don't use any of the handle versions if all you need is an array pointer. A handle is a pointer to a pointer and also a special LabVIEW data type that can be resized anytime but only with LabVIEw memory manager functions. It is only useful for DLLs specifically written to deal with native LabVIEW datatypes and linking to the LabVIEW memory manager functions for doing that.

The array data pointer is the only one that will work of the array types, or you can also use adapt to type and wire in a cluster if you are sure that that cluster is completely flat. A flat cluster is a cluster that contains only skalars (integers, floats, booleans) and other clusters with the same restrictions. Adpat to type will cause LabVIEW to pass the pointer to the memory area of that cluster to the DLL. For arrays and strings it will always pass the handle or the reference to the handle depending on the configuration.

The invalid buffer could be just an error caused by the fact that you do not yet have the correct information filled in. For instance some Windows API functions take structures whose first element is and integer indicating the size of the structure in bytes. Even if the function is supposed  to only return data in that cluster does it normally require that the caller has filled in that size element before passing it to the function.

Of course other inconsistent information in the cluster might also cause such an error.

Rolf Kalbermatter
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 10 of 50
(4,889 Views)