Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/31/2014 in all areas

  1. You cannot put launching of nested actors into Pre-Launch Init.vi. That will deadlock because Pre-Launch Init is mutually exclusive with any other actor launching (by design -- it provides the bottleneck where you can acquire multiple resources without worrying that other actors are acquiring those resources at the same moment). Acquisition of resources for references generally works best there. Doing your Launch Actor (soon to be Launch Nested Actor) there won't work. https://decibel.ni.com/content/thread/18246 is the thread you want... including my comments on why I believe you would never want to call "Handle Error.vi" in "Pre-Launch Init.vi"... it just can't really be the same handler when an actor is running as when an actor is not yet running. The things you do to "handle" the error are entirely different.
    1 point
  2. 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.
    1 point
  3. I am trying to solve a performance problem with my application and I have run into an issue I do not understand. For some reason, I cannot create a class data element that is a strictly typed vi reference. I can create a generic one just fine, but if I try to make it strict, I get an error. The reason I am trying to do this is to avoid the overhead and 'root loop' issues with the Open VI Reference call. In my application I am dynamically launching multiple child objects using a more generic 'handler' VI. I simply open a reentrant instance of this 'handler' vi, pass in the child class and the 'handler' calls my 'run' method in the child class via dynamic dispatch. The problem I ran into was the Open VI Reference was bogging down the system. So, I decided to use the Start Asynchronous Call with options 0x40 and 0x80. The idea was to open a single reference to my 'handler' when my application starts and then store this in the class data of an object that I pass to all my VIs (for data sharing). I would then use this reference to call the Start Asynchronous Call function (it requires a strictly typed vi reference). But, I was stopped when I tried to add the strictly typed vi reference to the class data. As a workaround to prove my fix would solve my speed issue, I created a global variable (horror!) and stored the strictly typed vi reference in that. I then used this global when calling the Start Asynchronous Call function. This worked fine and my performance issues are gone. But I would really like to put that reference in a class instead of in a global. I even tried using a generic vi refnum, thinking I could cast it to the strictly type refnum before sending it to the Start Asynchronous Call but I found that you cannot cast a generic VI refnum to a strictly typed vi refnum. So, any ideas? This does not seem like a strange thing to want to do. Perhaps there is some reasoning behind it that I am not aware of. Any thoughts on a way to accomplish my goal via a different route? thanks for any feedback, -John
    1 point
×
×
  • Create New...

Important Information

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