LAVA Forums Buy cool LAVA gear Forums RSS Feed

Welcome Guest ( Log In | Register )

> Related links

Visit our LabVIEW Wiki External Code Portal.


Tags
(This content has not been tagged yet)
 
Reply to this topic Start new topic
> Calling a dll that returns a buffer full of data, Works up to 255 points, but fails after that
george seifert
post Apr 4 2008, 04:08 PM
Post #1


Very Active
***

Member
Posts: 227
Joined: 19-August 05
From: Minneapolis, MN
Member No.: 2786
Using LabVIEW Since:1995
LV:8.20 ,. ,.
United States Nothing Selected Nothing Selected


I'm calling a dll that returns a buffer full of data. If I ask for up to 255 data points it returns the correct data. If I ask for more than 255 points LabVIEW gives an error and tells that memory may be corrupted. I preload the input to the dll with an array of the correct size. Any ideas what might be going on? Why the 255 point limit?

I've attached the VI, but I don't seem to be able to load the dll.

Attached File  Keyence_DataStorageGetData.vi ( 21.2K ) Number of downloads: 149


George

I should add that the dll is supposed to return up to 65536 data points.

This post has been edited by george seifert: Apr 4 2008, 04:27 PM


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
Ad
post Apr 4 2008, 04:08 PM
Post #















Tags
(This content has not been tagged yet)
Go to the top of the page
Quote Post
jdunham
post Apr 5 2008, 05:49 AM
Post #2


Very Active
***

Member
Posts: 200
Joined: 6-March 05
From: Mountain View, CA
Member No.: 1764
Using LabVIEW Since:1994
LV:8.5 ,. ,.
United States us_california Nothing Selected


QUOTE (george seifert @ Apr 4 2008, 09:08 AM) *
I'm calling a dll that returns a buffer full of data. If I ask for up to 255 data points it returns the correct data. If I ask for more than 255 points LabVIEW gives an error and tells that memory may be corrupted. I preload the input to the dll with an array of the correct size. Any ideas what might be going on? Why the 255 point limit?

I've attached the VI, but I don't seem to be able to load the dll.

Attached File  Keyence_DataStorageGetData.vi ( 21.2K ) Number of downloads: 149


George

I should add that the dll is supposed to return up to 65536 data points.


At least as imporant as loading the DLL would be posting the function prototype from the Keyence header file (and other C typedefs it uses).


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
rolfk
post Apr 7 2008, 07:21 AM
Post #3


<customize this text>
*****

Premium Member
Posts: 1012
Joined: 9-April 04
From: Rotterdam
Member No.: 349
Using LabVIEW Since:1992
LV:8.5.1 ,8.2.1 ,7.1.1
Netherlands Switzerland Nothing Selected


QUOTE (george seifert @ Apr 4 2008, 11:08 AM) *
I'm calling a dll that returns a buffer full of data. If I ask for up to 255 data points it returns the correct data. If I ask for more than 255 points LabVIEW gives an error and tells that memory may be corrupted. I preload the input to the dll with an array of the correct size. Any ideas what might be going on? Why the 255 point limit?

I've attached the VI, but I don't seem to be able to load the dll.

Attached File  Keyence_DataStorageGetData.vi ( 21.2K ) Number of downloads: 149


George

I should add that the dll is supposed to return up to 65536 data points.


I doubt very highly that your DLL is understanding LabVIEW datatypes. That is however what it is going to see if you use Adapt to Type. With that you tell LabVIEW to pass its array just as it is in memory, which will be a LabVIEW data handle and not an array data pointer.
Since it is an array of struct there is no trivial way to make LabVIEW pass it as a pointer. You will have to typecast the cluster array to a byte array (selecting little endian) then pass it as an array data pointer and on return decode the bytestream. There is really no other way other than writing a wrapper DLL in C doing that translation for you in C.

Rolf Kalbermatter


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
george seifert
post Apr 7 2008, 12:53 PM
Post #4


Very Active
***

Member
Posts: 227
Joined: 19-August 05
From: Minneapolis, MN
Member No.: 2786
Using LabVIEW Since:1995
LV:8.20 ,. ,.
United States Nothing Selected Nothing Selected


QUOTE (rolfk @ Apr 7 2008, 02:21 AM) *
I doubt very highly that your DLL is understanding LabVIEW datatypes. That is however what it is going to see if you use Adapt to Type. With that you tell LabVIEW to pass its array just as it is in memory, which will be a LabVIEW data handle and not an array data pointer.
Since it is an array of struct there is no trivial way to make LabVIEW pass it as a pointer. You will have to typecast the cluster array to a byte array (selecting little endian) then pass it as an array data pointer and on return decode the bytestream. There is really no other way other than writing a wrapper DLL in C doing that translation for you in C.

Rolf Kalbermatter


Rolf,
I suppose you're probably right that the dll isn't understanding what's being sent, but I still don't understand how I can get 255 elements of the array to work perfectly. I tried a zillion different ways to pass the data and they all crashed the system when I passed more than one element. So I figured I had to be close.

I have no way to do any C code so I was wondering if something else might work. Basically I expecting two 32 bit elements, one U32 and one Single, in each array element. Could I just send it an array of U32 that's twice as big as what I normally expect? I'm not sure though if I can convert the U32 to Single.

I zipped the VI and the dll. They're available here: Attached File  keyence.zip ( 94.65K ) Number of downloads: 64

Here's the data definition and prototype code from a Visual Basic example.

Public Enum LKIF_FLOATRESULT
LKIF_FLOATRESULT_VALID ' valid data
LKIF_FLOATRESULT_RANGEOVER_P ' over range at positive (+) side
LKIF_FLOATRESULT_RANGEOVER_N ' over range at negative (-) side
LKIF_FLOATRESULT_WAITING ' comparator result
End Enum

Public Type LKIF_FLOATVALUE
FloatResult As LKIF_FLOATRESULT ' valid or invalid data
Value As Single ' measurement value during LKIF_FLOATRESULT_VALID
End Type

Public Declare Function LKIF_DataStorageGetData Lib "LkIF.dll" (ByVal OutNo As Long, ByVal NumOutBuffer As Long, ByRef OutBuffer As LKIF_FLOATVALUE, ByRef NumReceived As Long) As Long


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
rolfk
post Apr 7 2008, 01:19 PM
Post #5


<customize this text>
*****

Premium Member
Posts: 1012
Joined: 9-April 04
From: Rotterdam
Member No.: 349
Using LabVIEW Since:1992
LV:8.5.1 ,8.2.1 ,7.1.1
Netherlands Switzerland Nothing Selected


QUOTE (george seifert @ Apr 7 2008, 07:53 AM) *
Rolf,
I suppose you're probably right that the dll isn't understanding what's being sent, but I still don't understand how I can get 255 elements of the array to work perfectly. I tried a zillion different ways to pass the data and they all crashed the system when I passed more than one element. So I figured I had to be close.

I have no way to do any C code so I was wondering if something else might work. Basically I expecting two 32 bit elements, one U32 and one Single, in each array element. Could I just send it an array of U32 that's twice as big as what I normally expect? I'm not sure though if I can convert the U32 to Single.

I zipped the VI and the dll. They're available here: Attached File  keyence.zip ( 94.65K ) Number of downloads: 64

Here's the data definition and prototype code from a Visual Basic example.

Public Enum LKIF_FLOATRESULT
LKIF_FLOATRESULT_VALID ' valid data
LKIF_FLOATRESULT_RANGEOVER_P ' over range at positive (+) side
LKIF_FLOATRESULT_RANGEOVER_N ' over range at negative (-) side
LKIF_FLOATRESULT_WAITING ' comparator result
End Enum

Public Type LKIF_FLOATVALUE
FloatResult As LKIF_FLOATRESULT ' valid or invalid data
Value As Single ' measurement value during LKIF_FLOATRESULT_VALID
End Type

Public Declare Function LKIF_DataStorageGetData Lib "LkIF.dll" (ByVal OutNo As Long, ByVal NumOutBuffer As Long, ByRef OutBuffer As LKIF_FLOATVALUE, ByRef NumReceived As Long) As Long


Yes treating it as array of int32 of double the size should work quite well. You can then typecast that back into an array of your cluster type although you may have to byteswap and word swap the whole array first to correct for endianess issues. Or maybe just swap the bytes and words of the integer part. That is always something best seen in trial and error.

Why it seemed to work for smaller arrays is probably because the DLL was in fact writing the first enum valu into the int32 that tells LabVIEW how many elements are in the array. As such you should have seen a swapping of the float and enum in comparison to what the VB code would indicate. With smaller arrays the overwriting did not cause to bad problems but with longer arrays it somehow set of a trigger.

Rolf Kalbermatter


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post
george seifert
post Apr 7 2008, 02:41 PM
Post #6


Very Active
***

Member
Posts: 227
Joined: 19-August 05
From: Minneapolis, MN
Member No.: 2786
Using LabVIEW Since:1995
LV:8.20 ,. ,.
United States Nothing Selected Nothing Selected


QUOTE (rolfk @ Apr 7 2008, 08:19 AM) *
Yes treating it as array of int32 of double the size should work quite well. You can then typecast that back into an array of your cluster type although you may have to byteswap and word swap the whole array first to correct for endianess issues. Or maybe just swap the bytes and words of the integer part. That is always something best seen in trial and error.

Why it seemed to work for smaller arrays is probably because the DLL was in fact writing the first enum valu into the int32 that tells LabVIEW how many elements are in the array. As such you should have seen a swapping of the float and enum in comparison to what the VB code would indicate. With smaller arrays the overwriting did not cause to bad problems but with longer arrays it somehow set of a trigger.

Rolf Kalbermatter


Rolf,

First of all. Thanks so much for all your help. Can I please bug you for a little more help in setting up the call? I've been trying to get it to work with the int32 array, but I'm not having any luck. I got one combination to sort of work (Type -Adapt to Type, Data format - Array Data Pointer), but it crashed after I ask for 127 data points which translates to 254 elements in the array. There's that same upper limit again. I also tried Type = Array, Data type = int32, Dimensions = 1, Array format = Array Data Pointer, Minimum size = <None> with the same results.

I did just manage to get one thing to work. I used the above settings, but used a int64 element and just asked for the right number of elements (instead of twice the number). Now I can get back all the values in the instruments (12500). Glancing at the received numbers I think they make sense. One of the 32 bit numbers should be constant at 0, which it is. Now maybe I just have to convert the other 32 bit number like you said.

Just to beat a dead horse a bit more. I wasn't seeing any swapping of the float and enum in my original code. I was easy to tell because the ENUM was 0 (indicating a valid value was sent) and the float value agreed with the value returned by the company's sample code.

George

Success! A simple typecast to Single after separating out the upper 32 bits worked.

It would be nice to know why sending an array of int32 of twice the size didn't work. I'm lucky the data fit in 64 bits. I don't what I'll do if a situation comes up where I need more bits.

George


Tags
(This content has not been tagged yet)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic

 




Time is now: 2nd December 2008 - 03:34 AM