Jump to content

LabVIEW Memory Manager Functions


Recommended Posts

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)?



CmpbpHg.png9pZkf5u.png

pLdxtAC.png

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 */}
Link to comment

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.

  • Like 2
Link to comment
  • 3 weeks later...

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!

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

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