GeorgeG Posted March 9, 2014 Report Share Posted March 9, 2014 I am trying to use the LabVIEW memory manager functions (DS/AZNewHandle,DS/AZSetHandleSize,DS/AZDisposeHandle,others) to populate the array of clusters shown below. The number of elements and the string lengths will not be known before the DLL call, so I am really trying to make it work as shown.I've tried quite a few combinations of Type/Data Format/Manager Function calls, but I consistently crash LabVIEW or create severe memory leaks. It isn't even 100% clear to me whether this is in Data Space or Application Zone. Google has been decidedly unhelpful.Can anyone help me /* insert code here */ (see below)?DLL Code generated by LabVIEW (right click on node and "Create C File": /* Call Library source file */#include "extcode.h"/* lv_prolog.h and lv_epilog.h set up the correct alignment for LabVIEW data. */#include "lv_prolog.h"/* Typedefs */typedef struct { int32_t Numeric; LStrHandle String; } TD2;typedef struct { int32_t dimSize; TD2 Cluster[1]; } TD1;typedef TD1 **TD1Hdl;#include "lv_epilog.h"int32_t funcName(TD1Hdl *data);int32_t funcName(TD1Hdl *data){ /* Insert code here */} Quote Link to comment
Rolf Kalbermatter Posted March 9, 2014 Report Share Posted March 9, 2014 First, the distinction between AZ and DS memory space has long ago been removed. The functions remained for backwards compatibility but really allocate exactly the same handle. Second you shouldn't try to do this if you don't have a very deep understanding of C memory pointers. I can give you a principle idea, but can't do all the work for you. You will likely have to tweak this code and it may even contain syntax errors as I'm writing it just from memory without any compiler check. So watch out and reconsider if you really want to go this path. /* Call Library source file */ #include "extcode.h" /* lv_prolog.h and lv_epilog.h set up the correct alignment for LabVIEW data. */ #include "lv_prolog.h" /* Typedefs */ typedef struct { int32_t Numeric; LStrHandle String; } TD2; typedef struct { int32_t dimSize; TD2 Cluster[1]; } TD1; typedef TD1 **TD1Hdl; #include "lv_epilog.h" MgErr funcName(TD1Hdl *data); MgErr funcName(TD1Hdl *data) { MgErr err; int32 i, strLen, arrLen = ...; if (*data) { if ((**data)->dimSize > arrLen) { // Deallocate all contents in Clusters that get removed when resizing the array down for (i = arrLen; i < (**data)->dimSize, i++) { LStrHandle *str = &((**data)->Cluster[i].String); if (*str) { DSDisposeHandle(*str); *str = NULL; } } } err = DSSetHandleSize(*data, sizeof(int32) + arrLen * sizeof(TD1)); } else { *data = DSNewHClr(sizeof(int32) + arrLen * sizeof(TD1)); if (!*data) err = mFullErr; } if (!err) { TD2 rec = (**data)->Cluster; for (i = 0; i < arrLen; i++, rec++) { rec->Numeric = i; strLen = strlen(sourceString); err = NumericArrayResize(uB, 1, (UHandle*)&rec->String, strLen); if (err) return err; MoveBlock(sourceString, LStrBuf(*(rc->String)), strLen); LStrLen(*(rec->String)) = strLen; } (**data)->dimSize = arrLen; } return err; } This should give you a start. Please note that I did try to make some provisions to properly deallocate internal resources if the array resize would result in a shortening of the incoming array. However the error handling is not perfect at all. Currently if the code errors out because of anything then the array could actually stay in an inconsistent state, resulting in memory leaks, since LabVIEW wouldn't know about the already newly allocated array records. However in this example this is not really a big problem as the only errors that could happen are memory manager errors and once such an error has occurred you'll have to restart LabVIEW anyways. But if you add your own code in there to actually retrieve the data from somewhere you might run into more norrmal errors and just bailing out like this in the array fill in loop could have really bad consequences in terms of memory leaks. 2 Quote Link to comment
GeorgeG Posted March 31, 2014 Author Report Share Posted March 31, 2014 Thanks Rolf! I thought I'd written code quite similar to yours, but it didn't work. Following along with your suggestions I did get something working... go figure. Pointers and handles are tricky beasts... not so impossible to understand, but very devil-in-the-details. I wasn't able to use the DSSetHandleSize function though... anytime I executed that branch of code an exception would get thrown (somewhere else). So for now I am just deallocating the whole thing, disposing the handle, and starting over (instead of trying to "resize"). Thanks again for your help! 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.