george seifert Posted April 5, 2008 Report Share Posted April 5, 2008 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 LV 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. Download File:post-2786-1207325057.vi George I should add that the dll is supposed to return up to 65536 data points. Quote Link to comment
jdunham Posted April 6, 2008 Report Share Posted April 6, 2008 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 LV 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. http://lavag.org/old_files/post-2786-1207325057.vi'>Download File:post-2786-1207325057.vi 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). Quote Link to comment
Rolf Kalbermatter Posted April 8, 2008 Report Share Posted April 8, 2008 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 LV 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. http://lavag.org/old_files/post-2786-1207325057.vi'>Download File:post-2786-1207325057.vi 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 Quote Link to comment
george seifert Posted April 8, 2008 Author Report Share Posted April 8, 2008 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: http://lavag.org/old_files/post-2786-1207571374.zip'>Download File:post-2786-1207571374.zip 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 Quote Link to comment
Rolf Kalbermatter Posted April 8, 2008 Report Share Posted April 8, 2008 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: http://lavag.org/old_files/post-2786-1207571374.zip'>Download File:post-2786-1207571374.zip 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 Quote Link to comment
george seifert Posted April 8, 2008 Author Report Share Posted April 8, 2008 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 Quote Link to comment
alemarcondes Posted March 6, 2013 Report Share Posted March 6, 2013 QUOTE (rolfk @ Apr 7 2008, 08:19 AM) 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 Hi George, I'm having the same problem, but unfortunately I couldn't resolve with these tips. So, could you post your VI that is working? Thanks, Alexandre Marcondes. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.