Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 07/22/2015 in all areas

  1. While it's a breaking change to modify this now, the original of writing seconds since january 1. 1904 as a timestamp to SQLLite is truely broken too. So I would investigate if you can demote the current method as depreciated and remove it from the palettes and add a new one that does the right thing. Existing applications using that function will still work as they used too, and still use a broken timestamp while new developments would use the right method. Also document that difference somewhere for anyone wanting to read databases written with the old method to use the depreciated method for reading, but a string reminder to not use it for new development.
    1 point
  2. LabVIEW's timestamp format is explicitedly defined as number of seconds since midnight January 1, 1904 GMT. There is no reason LabVIEW needs to adhere to any specific epoch. On Windows the system time epoch is number of 100 ns, since January 1, 1601, and Unix uses indeed January 1, 1970, while the MacOS used January 1, 1904 (yes LabVIEW was originally a MacOS only application! ). And as curiosa, Excel has a default time definition of number of days since January 1, 1900, although due to a mishap when defining that epoch and forgetting about that 1900 wasn't a leap year, the real epoch starts on midnight December 31, 1899. But there is a configuration option in Excel to shift this to the MacOS time epoch! It's definitely a good thing that they stick to the same time epoch on all LabVIEW platforms, and since the MacOS one was the first to be used by LabVIEW, it's a good choice to stick with that. If your API has a different epoch you have to provide functions to convert between the LabVIEW epoch and your API epoch and vice versa.
    1 point
  3. Would this do, then? The assumption is that the first column of the line is the pin number, then further columns can only be ON, OFF, a waiting time in ms or empty to end the sequence.
    1 point
  4. Hello, I am passing some data from dll to labview. It is an array of clusters. Cluster looks like this: typedef struct { LStrHandle longname; LStrHandle name; uint8_t intraonly; uint8_t lossless; uint8_t lossy; } CodecInfo, **CodecInfoHdl; typedef struct CodecInfoArr { int32_t dimsize; CodecInfo Arr[1]; } CodecInfoArr, **CodecInfoArrHdl; But I think it is reproducable with any kind of array of clusters where are other handles, like LStrHandle in my case. The operation is pretty straightforward. I check the incoming handle, I handle the situation where it is empty or filled with data and in the next step I have an empty handle to work with. So far I have an array handle returned from DSNewHandle allocated for the resulting array size. I start copying the data, but since there are strings involved, I call my general char2LStrHandle function to fill string handles. void PrintChar2LVStrHandle(const char *charstr, LStrHandle *StrHandleP, bool forcenew = false) { MgErr error = mgNoErr; std::string temp = ""; if (charstr) { temp.assign(charstr); } if ((!IsHandleEmpty(StrHandleP)) && !forcenew) { error = DSDisposeHandle(*StrHandleP); if (error != mgNoErr) throw(WrpExcUser("PrintChar2LVStrHandle()", error)); } *StrHandleP = (LStrHandle)(DSNewHandle(Offset(LStr, str) + sizeof(uChar))); if (*StrHandleP == nullptr) throw(WrpExcUser("Could not allocate string handle", CUSTOMERROR)); //(**StrHandleP)->cnt = 0; error = LStrPrintf(*StrHandleP, (CStr)"%s", temp.c_str()); if (error != mgNoErr) throw(WrpExcUser("Could not print to string handle", error)); } There is a lot of junk&unnecesary code, but the core of the function is to check the handle, and if it is valid, just print into it. The function that checks the handle looks like this: bool IsHandleEmpty(const LStrHandle *h) { MgErr err, heaperr = mgNoErr; err = DSCheckHandle(*h); //heaperr = DSHeapCheck(0); if (err) return true; return false; } It is just a stupid wrapper around DSCheckHandle. Now the problem is, that with the way the array handle allocated the array elements, some handle pointers, from time to time point to memory so unfortunately, that the array elements that get processed later have string handle pointer pointing to memory that is already filled with data from previous array filling loop iterations. It is not the exactly same memory, since the data is little off (garbage, count is wrong etc.), but it is sufficient enough for the DSCheckHandle return, that the handle is valid. So the memory gets a treatment like it would be a real handle and it corrupts the labview heap, so when the data gets deallocated, LabView / runtime will crash. So far I tackled the solution with simple optional parameter (bool forcenew = false) and went through all the function references in code to set the flag if the data comes from new array handles. Finally the question: Is there more elegant solution to this, somehow correctly check the incoming string handle ?
    1 point
  5. It's generally correct what JKSH writes when the handle containing the handles is allocated by yourself. However if that array of CodecInfo structs comes from LabVIEW there are strict rules that can be observed and must be followed when returning such data to LabVIEW. Anything beyond the number of elements indicated in the array is uninitialized although the actual array handle space may be bigger but never smaller than needed for the number of valid elements. The only exception to this are ampty array handles which can be both either a valid handle with a number of elements equal to 0 OR a null handle itself. So when receiving handles from LabVIEW you should always check for null and depending on that do DSNewHandle/DSNewHClr or DSSetHandleSize. When resizing a handle existing elements need to be resized and appended elements always created. Removed elements when making an array smaller must always be recursively deallocated as they don't exist for LabVIEW anymore once the array length has been readjusted to a smaller size and would therefore create a memory leaks. If you allocate both the array handle as well as the contained handles inside the array in the same code section without returning in between to the LabVIEW diagram it is entirely up to you if you want to use DSNewHandle or DSNewHClr, as the values inside the newly allocated array need to be initialized anyhow explicitly. The latter requires more execution time but may be faster if you need to initialize most elements in there to 0 or an empty handle anyways. Also it may be a little safer when someone later makes modifications to the code as null pointer dereferencing has a higher chance of crashing than accessing uninitialzed pointers, so debugging is easier.
    1 point
  6. Yes yes, you are completely right. I was kinda dull and supertired when finaly revealing where the problem of my crashing was, so I just lazy posted here However, I think it is better to use DSNewHClr, that correctly initialized the handles to nullptr. It feels much safer, so all the if(*ptr) have predictible result. Thx for answer.
    1 point
  7. Hi, When would the LStrHandles ever be valid? If you allocate a new CodecInfo array, then all the LStrHandles are uninitialized (that means they are never valid). So the solution is this: For all of the LStrHandles inside your new array of clusters, always call DSNewHandle() and never call DSCheckHandle(). Like I mentioned before, your new LStrHandles are uninitialized pointers. You must never call a function (including DSCheckHandle()) to perform an action on an unitialized pointer. If you do, you will get undefined behaviour (and usually crash) -- This applies to all C/C++ code, not just LabVIEW interface code.
    1 point
  8. In case this is useful to anyone else who is also too cheap to spring for Machine Vision... I implemented a simple blob finding algorithm based on Blob Detection - The Lab Book Pages. It takes a 2D array of DBL, which should be easy to create from any monochrome image. You can set a range of values to count as "foreground"; the default is 1 to +Inf. I use an intensity graph to display the input, which results in an apparent rotation of your image. Mentally rotate the intensity graph 90 degrees to the right, to see your original image, e.g. if you created the data by reading a picture file and selecting one color. The output "blobs" will be oriented like your original image. Values of 0 in the output indicate no blob, i.e. nothing there. Values 1 or greater are the blob numbers, in the order encountered. Labview 2012; OpenG array package required. Use blob_find_DBL.vi by itself (it's in Common\Calculations) or with test_blob_find.vi (in Common\tests, and you will need a PNG file to read). Common.zip
    1 point
  9. Because state-machines are hard and have to be debugged with witchcraft. So just avoiding the problem means you don't need tools for that problem.
    1 point
  10. I think it's a chicken-and-egg problem: NI doesn't polish it because there are few users; few users use it because it's not polished. I don't think it's the learning curve because the concept of statecharts is quite intuitive, and should be familiar to many people who haven't used LabVIEW before. I used statecharts for one large project once, for coding complex logic in a CompactRIO. The main issues I had were: Deployment took forever. Bugginess, like you said. Modifying triggers is tedious (and you can't share triggers between different statecharts) Managing static reactions is tedious (you can't reorder them or insert a new one in the middle; you gotta delete them and re-add them in the correct order)
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.