Resizing an array of struct inside a DLL using the memory manager

Hi all,
I dug deep inside the boards, but wasn't able to find a solution for my problem.
I'm building a dll, which does some imageprocessing and should return an array of structs to labview, with one struct for every element in the image.
As I don't know the number of elements beforehand and the limit of the number is numbers of magnitude larger then the expected one, I don't want to allocate such a huge chunk of memory prior to the dll call in labview.
In a former version I used a 2d array for the elements, where each row holds the values of every element. Here I used the NumericArrayResize-function, which worked quite well. But I have to add more sub-processes and using structs (or clusters in labview) appears to be more usefull and cleaner for me, in addition I had to cast some of the elements back and foreward a few times.
So one element-struct should hold 2 singles and 1 uint32. My question is now, how can I resize this array of struct with memory manager functions as the NumericArrayResize-functions does not suit this purpose?
(Accessing a given array of structs inside the DLL and after that reading the changed values in Labview is surprisingly easy )
Thanks in advance
Solved!
Go to Solution.

Well, I was able to solve it myself. I found this thread, where the first post of rolfk made me thinking. It appeared to me, that the numericarrayresize-function behaves very similar to the realloc-function of c. So I used the type unsigned int 8 (which is just one byte) and multiplied it by the number of bytes used by one struct, in my case 12 bytes (4+4+4) and then multiplied it by the number of structs (elements in the image) i have. Luckily it worked and the memory block was resized exactly as I wanted it to be. Important to note: do not forget to adjust the size element of the handle, otherwise Labview does not know about the changed size.

Similar Messages

  • How to get a component's value inside a repeater using the component's id?

    Hello I'm using a repeater with an httpservice as dataprovider.
    in this repeater, I have a <mx:Panel> containing a <mx:Text>, a <mx:ButtonBar>, and a <mx:HSlider>.
    I need to get the text property of the Text component and the HSlider's value when the slider's value changed. (using the "change=..." property of my HSlider).
    How to do this as I have to know which Panel, HSlider, and which Text has been activated by the slider change?
    Thanks for your help

    This might help you.
    <?xml version="1.0"?>
    <!-- repeater\GetItem.mxml -->
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
      <mx:Script>
        <![CDATA[
             import mx.controls.Alert;
           [Bindable]
           public var myAC:Array=[1,2,3,4];
           public function getData(event:Event):void{
                     Alert.show(event.currentTarget.text);
                     Alert.show(mySlider[event.target.repeaterIndices].value);
        ]]>
      </mx:Script>
      <mx:Repeater id="myrep" dataProvider="{myAC}">
          <mx:TextInput change="getData(event);" />
          <mx:HSlider id="mySlider" maximum="200" minimum="50" value="67"  snapInterval="1"/>
      </mx:Repeater>
    </mx:Application>

  • Is it possible to create Qt Widgets inside After Effects using the SDK?

    Hi,
    I would like to use Qt to create Dialogs and Widgets inside AfterEffects.
    I started out with the Panelator example in the SDK. I can include QtGui into the project, but as soon as I create any object with QObject as a base-class After Effects crashes immediately with the following error: '[...] could not be loaded (48::46)'
    When I try delay load QtCore.dll and QtGui.dll I can at least start the plugin and see, that the crash happens in the initializer of the QObject.
    I use
    VS 2010
    QT 4.8.5
    and my buildenvironment is x64
    I was wondering if there is any kind of incompatibility of embedding Qt in After Effects (due to linker/compiler setting or defines or something like this).
    This is the debugger output:
    Locals:
    Threads:
    My code in the Panel-constructor function:
        int argc = 0;
        char *argv[1] = {""};
        QApplication* a = new QApplication(argc, argv); // THE ERROR OCCURS IN THIS LINE. for a test I exchanged it to QWidget* w = new QWidget(); and it happens as well.
        QWidget* w = new QWidget();
        w->show();
        a->exec();
    Outside of AfterFX Qt works fine and I also can delay-load QtGui and QtCore.
    If anyone of you already has experience in using QT in AfterEffects, I would really appreciate your help!
    Thanks in advance.

    It finds QtGui and QtCore, it misses out some other dependencies further down in the hierarchy of USER32.DLL:
    Which doesn't seem to disturb if I don't include and use QT:

  • Call to a C++ DLL, using JNI - C++ method has char*

    I am trying to link into an existing C++ Dynamically Linked Library(DLL) using the Java Native Interface(JNI).
    All goes fine, and the library loads into the current program, however when I try to call the function, it crashes. The function has char pointers, and I haven;t been able to get Java to simulate them. Is there a way?????
    I have tried using and array of chars .....char[], and String, but no dice.
    Any suggestions O'learned Java ones??

    It will be necessary for you to write a JNI adapter in C/C++ to accomplish this. Java character strings and arrays are very different from those of C/C++ and you'll have to use JNI functions to adapt.
    Chuck

  • Cannot run Simulink dll at the same time as running real-time target VI

    Hello
    What I am trying to do is run a model dll created in Simulink to control some servo's through a CompactRio 9014. 
    At the moment I have managed to create three VIs
    1) In the FPGA target that performs the PWM on a desired channel
    2) That takes the value of a network variable which contains the position required and feeds that to the 1st VI
    3) A VI that runs on the host computer that modifies the value of the network variable to change the position
    I can get these three VIs working and the servo controlled, but when I try to update the value of the network variable using the simulation, by deploying the simulation to the RT target and running it, it says
    'Access denied: This target is already in use by another project or host computer.'
    I assume as this is because the project is already connected to the cRio, so I disconnect and am able to deploy the model files. 
    However when I try to run one of the VIs in the RT Targer along with the simulation I get the error:
    'This VI is downloaded on the target but is not present in the project you are attempting to deploy.  All VIs on the target will be closed unless you choose to add the missing VI to the project.'
    With a large number of missing VIs...
    Would I be doing this wrong, i.e. is there a much simplier way to control the FPGA inputs using the simulation, or is there something I could have missed?
    Thanks
    Geoff
    Solved!
    Go to Solution.

    Hi Geoff,
    It seems that you are on the right track except for some concepts that I
    want to review:
    A CompactRIO or cRIO has 3 different components:
    1)     
    Real-Time controller (in your case a 9014)
    2)     
    FPGA backplane (this could be a 9102, or a 9103, 910x,
    etc)
    3)     
    I/O modules (like a 9401, 9263, etc)
    When you write an application for cRIO you usually have three different VIs:
    1)     
    Host VI – This VI is used as a user interface and runs in
    Windows (under “My Computer” in the LabVIEW project) This VI is optional because
    you might want to run the cRIO headless.
    2)     
    RT VI – This is the VI that runs in the cRIO controller
    (in your case the 9014).  This VI lives
    under the cRIO target in your LabVIEW project. 
    3)     
    FPGA VI – This is the VI that runs in the cRIO
    backplane like a 9102.  This lives under
    the cRIO >> FPGA target in the LabVIEW project.
    The ONE application that I was talking about in my last post is for the RT
    VI.  There can only be one RT VI that
    gets deployed.  If you want to run
    multiple VIs in the cRIO RT, then you need to run those VIs as subVIs of one
    top level VI.
    LabVIEW Simulation Interface Toolkit (SIT) has a tool called the SIT
    Connection Manager that creates two of these three VIs for you (the RT and the
    Host VIs).
    Please refer to the following link about the SIT Help.  Go to the How To section.  It is organized in a kind of step by step
    tutorial.
    http://zone.ni.com/reference/en-XX/help/371504D-01/
    In your case it is going to be a bit more difficult because of two things:
    One, you are using a VxWorks target. 
    Two, you want to use your own FPGA VI.
    Let’s address each one of them:
    1)     
    VxWorks target- To use the SIT Connection Manager you
    need to use a DLL not an OUT file, even though you need the OUT file for the cRIO VxWorks target.  The reason is
    that this tool needs to read the compiled model to know what the
    parameters, signals, inports and outports of your model are.  Because the tool runs in Windows you cannot
    open an OUT file (meant for a different OS) so you need to give it a DLL. 
    For this reason you will need to compile your model file into an OUT
    file and a DLL.  Once you give a DLL to
    the Connection Manager and you select your cRIO as the execution target, keep
    doing the rest of the steps as the help says. 
    LabVIEW will identify that you are using a VxWorks target and will
    download the OUT file to the cRIO.
    2)     
    Custom FPGA VI – LabVIEW SIT has some FPGA bitfiles
    (compiled FPGA VIs) that it can use. 
    When you open the SIT connection manager and go to the Hardware IO
    mapping section it asks you to select the bitfile.  If you want, you can select one of the
    shipping bitfiles but iIf you
    want to use your own, then you will need to do some changes to your FPGA VI , recompile it and
    save the bitfile in a specific location with a specific name.
    Please refer to the following link for
    instructions on how to create your custom FPGA VI:
    http://zone.ni.com/reference/en-XX/help/371504D-01/lvsithowto/sit_h_custfpga/
    What I would suggest is that you start with a very simple example and using
    one of the shipping bitfiles.  Look into
    the following path for a very simple Sine wave generation example:
    C:\Program Files\National Instruments\LabVIEW 8.6\examples\Simulation
    Interface\Sine Wave
    Because you are running a VxWorks target you will need to recompile this
    example model sinewave.mdl to an OUT file.
    To get a better understanding of what SIT does you might
    want to check some quick videos. Go to
    http://sine.ni.com/nips/cds/view/p/lang/en/nid/11763  and under the
    resources tab there are two videos called Demo - <something>...
    Hope this helps and let me know if you have more questions.
    Ricardo
    National InstrumentsSystems Engineering

  • I have convert JAR to DLL using VisualCafe, how to use it in VB?

    Hello all,
    I have successfully convert/compile my Jars file to DLL files following the steps given in the VisualCafe Expert Edition help file.
    Let say my Jars file contain the following class & method:
    class1 setName(String sData)
    class1 getName()
    class2 mtd_Open(String sFileName)
    class2 mtd_Save(String sFileName)
    ... so on ...
    Does anyone know how to use the DLL in the VB program? Let say, I want to use the method "mtd_Open(String sFileName)" in the class "class2" in my VB program, how do I code this in VB? Please help...
    Thanks for your time.

    suggest that donot convert jar to dll.
    use the jar in VB directly through JNI technology of SUN JAVA.
    peter
    JawaBeginer (A powerful JavaIDE tool for Java Programmer, exp: beginer)
    http://www.pivotonic.com

  • Memory Management in LabView / DLL

    Hi all,
    I have a problem concerning the memory management of LabView. If my data is bigger than 1 GB, LabView crashes with an error message "Out of Memory" (As LabView passes Data only by value and not by reference, 1 GB can be easily achieved). My idee is to divide the data structure into smaller structures and stream them from Hard Disk as they are needed. To do so, i have to get access to a DLL which reads this data from disk. As a hard disk is very slow in comparison to RAM, the LabView program gets very slow.
    Another approach was to allocate memory in the DLL and pass the pointer back to LabView...like creating a Ramdisk and reading the data from this disk. But memory is allocated in the context of Labview...so LabView crashes because the memory was corrupted by C++. Allocating memory with LabView-h-Files included doesnt help because memory is still allocated in the LabView context. So does anybody know if it's possible to allocate memory in a C++-DLL outside the LabView context, so that i can read my Data with a DLL by passing the pointer to this DLL by LabView? It should work the following way:
    -Start LabView program--> allocate an amount of memory for the data, get pointer back to labview
    -Work with the program and the data. If some data is needed, a DLL reads from the memory space the pointer is pointing at
    -Stop LabView program-->Memory is freed
    Remember: The data structure should be used like a global variable in a DLL or like a ramdisk!
    Hope you can understand my problem
    Thanks in advance
    Christian
    THINK G!! ;-)
    Using LabView 2010 and 2011 on Mac and Win
    Programming in Microsoft Visual C++ (Win), XCode (Mac)

    If you have multiple subvis grabbing 200MB each you might try using the "Request Deallocation" function so that once a vi is done processing it releases the memory.
    LabVIEW Help: "When a top-level VI calls a subVI, LabVIEW allocates a data space
    of memory in which that subVI runs. When the subVI finishes running, LabVIEW
    usually does not deallocate the data space until the top-level VI finishes
    running or until the entire application stops, which can result in out-of-memory
    conditions and degradation of performance. Use this function to deallocate the
    data space immediately after the VI completes execution."
    Programming >> Application Control >> Memory Control >> Request Deallocation
    I think it first appeared in LabVIEW 7.1.
    Message Edited by Troy K on 07-14-2008 09:36 AM
    Troy
    CLDEach snowflake in an avalanche pleads not guilty. - Stanislaw J. Lec
    I haven't failed, I've found 10,000 ways that don't work - Thomas Edison
    Beware of the man who won't be bothered with details. - William Feather
    The greatest of faults is to be conscious of none. - Thomas Carlyle

  • Hyper V Cannot be installed as Hypervisor is already running inside windows 8.1 ( which is a VM inside a windows 8 hyper v manager)

    Hi, 
    Although it is not concerned with windows server. Please help with this issue.
    I Installed windows 8.1 OS inside Windows 8 using hyper V manager.
    Then i installed visual studio 2013 update and i tried to run windows phone 8.1 emulator. 
    It said, one of the hyper v components is not working correctly. So, i disabled and enabled hyper v features using "Turn of windows features on or off" settings.
    But this time "Hyper V platform feature was installed"
    When i hover my mouse over that it said "Hyper V cannot be installed: hypervisor is already running"
    Please help me.

    Windows phone emulators are virtual machines. So if you installed visual studio to the virtual machine nothing can be done. Hyper-v cant be run inside of virtual machine.

  • How do I pass an array of structs to a C function using the dll flexible prototype adapter?

    What I want to do is pass into a C dll function a variably sized Array of structs of type TPS_Data. My Code compiles but when I run it in TestStand, I get an error -17001; Program Error. "Cannot allocate 0 size buffer Error in parameter 2, 'OpenFrdData'."
    I've allocated the Array of structs, and all of the information is there before I call my function, so is it my prototype? Or am I asking too much of the DLL Flexible Prototype Adapter to pass an Array of Structs?
    I can pass in a single struct of type TPS_Data and that works, but not an array.
    Here's the relevent code:
    typedef struct TPS_DATA
    char Report_Number[256];
    char System_Name[256];
    char Open_Date[256];
    char UUT_Part_Number[256];
    char UUT_Serial_Number[256];
    char UUT_Name[256];
    char Open_Employee_Name[256];
    char Open_Employee_Number[256];
    char Close_Employee_Name[256];
    char Close_Employee_Number[256];
    char Close_Date[256];
    } TPS_Data;
    typedef struct TPS_DATA_ARRAY
    TPS_Data DataRecord;
    } TPS_DataArray;
    long __declspec(dllexport) __stdcall OpenDialog (CAObjHandle Context, TPS_DataArray *TpsData[], const char *psFaultStr, char *sComments, const int nCount);

    OK,
    I can pass the data to the DLL function, using the following types:
    typedef struct StringArrayType
    char string[10][256];
    } StringArray;
    typedef struct MultiStringArrayType
    StringArray Record[10];
    } MultiStringArray;
    void __declspec(dllexport) __stdcall ATP_TestStructPassing(StringArray Strings)
    return;
    void __declspec(dllexport) __stdcall ATP_TestMultiStructPassing(MultiStringArray *Strings)
    return;
    But when the MultiStruct function Exits, TestStand reports an Error:
    -17501 "Unexpected Operating System Error" Source: 'TSAPI'
    There doesn't seem to be a way around this, and once the error occurs, I have to force quit TestStand. I've included the sequence file, and the dll code can be compiled from the fun
    ctions shown above.
    Any thoughts on how to get around this error would be greatly appreciated.
    Attachments:
    StructArrayPassing.seq ‏16 KB

  • How to pass a struct to a DLL function and accessing it in another VI

    Hi friends,
                       I am new to labview. I need to create a demo program in labview ,for displaying image from our own image capturing system. We have a  DLL ( build in VC++) containing functions for capturing image from our system. Now I need to create a VI library for some of functions in DLL and Create a Demo program using those created subvi library . I used "Call Function node" and created some of subvi's.
     Some of our DLL functions need to pass struct pointers.  Our function prototype will be similar to the following function.
    __declspec(dllexport) int __stdcall Initialize( unsigned char *imagebuffer,struct config *Configuration);
    The passed struct is similar to
    struct config
      double                val1[3];
      unsigned short   val2;
      bool                    val3;
      bool                    val4[3];    
      unsigned char    val5;    
      unsigned char   val6[3];
      bool                    val7[26];
    For passing "unsigned char *imagebuffer"  I initialized array with "Numeric constant " and set the size of the array and send to the function.
    The problem here is, I used this array in one of the subvi. 
    How can I use the returned imagebuffer array  in my main demo program. How to connect the image array to subvi "Connecter Pane"
    And  which control  can I use to display the image. The image data I get is form of 1-D Array .
    The second problem is,
                                 For passing the structure,  I used "Bundle " and filled the bundle with all the datatypes as in my struct and passed to the function. Is it correct ?  How to access this bundle after returned from function  in another Vi. ie.) How to connect this bundle to the connter pane ?
    Thanks for your valuable suggestions.
    aajjf.
    Message Edited by aajjf on 04-19-2007 05:34 AM

    aajjf wrote:
    Hi friends,
                       I am new to labview. I need to create a demo program in labview ,for displaying image from our own image capturing system. We have a  DLL ( build in VC++) containing functions for capturing image from our system. Now I need to create a VI library for some of functions in DLL and Create a Demo program using those created subvi library . I used "Call Function node" and created some of subvi's.
     Some of our DLL functions need to pass struct pointers.  Our function prototype will be similar to the following function.
    __declspec(dllexport) int __stdcall Initialize( unsigned char *imagebuffer,struct config *Configuration);
    The passed struct is similar to
    struct config
      double                val1[3];
      unsigned short   val2;
      bool                    val3;
      bool                    val4[3];    
      unsigned char    val5;    
      unsigned char   val6[3];
      bool                    val7[26];
    For passing "unsigned char *imagebuffer"  I initialized array with "Numeric constant " and set the size of the array and send to the function.
    The problem here is, I used this array in one of the subvi. 
    How can I use the returned imagebuffer array  in my main demo program. How to connect the image array to subvi "Connecter Pane"
    And  which control  can I use to display the image. The image data I get is form of 1-D Array .
    The second problem is,
                                 For passing the structure,  I used "Bundle " and filled the bundle with all the datatypes as in my struct and passed to the function. Is it correct ?  How to access this bundle after returned from function  in another Vi. ie.) How to connect this bundle to the connter pane ?
    Thanks for your valuable suggestions.
    aajjf.
    Message Edited by aajjf on 04-19-2007 05:34 AM
    You say nothing about how your cluster looks but I'm afraid you did the standard error here and placed arrays in it. That is not what the C structure is representing for several reasons.
    First fixed size arrays in C are inlined inside a structure, so are not a pointer but for the case of your val1 element three doubles.
    Second although not relevant here because of above point: LabVIEW arrays are not the same as C arrays. LabVIEW uses a pointer to a pointer and has the size of the array in elements prepended to the array data. C simply uses a pointer and all the rest is the programmers sorrow. The Call Library Node does convert the top level element of variables you pass according to the type configuration of that parameter but does no conversion of internal elements at all. So passing clusters with anything like arrays or strings is always wrong unless the DLL is aware of the specific datatypes LabVIEW uses.
    Last but not least you can end up with alignment issues. Elements in structures are aligned by every C compiler to a certain value. This value can be defined by the programmer in the project settings or for Visual C through #pragma pack() statements in the C code. The alignment rule says that an variable is aligned to the smaller of the two values that are either a multiple of the variable element size or the alignment setting. Most 32bit code nowadays uses 8 bit default alignment but LabVIEW always uses 1 byte. In your case there is nothing to observe since the large variables are at the beginning. Otherwise you might have had to insert filler elements in the LabVIEW cluster.
    One last thing bool is a C++ type only. Its size is 1 byte and incidentially this is the same LabVIEW uses for Booleans.
    Rolf Kalbermatter
    Rolf Kalbermatter
    CIT Engineering Netherlands
    a division of Test & Measurement Solutions

  • Array of doubles filled by DLL contains weird values

    Hello everyone
    I am working on a DLL invocation which needs to resize and fill an array of doubles named 'values' (2nd to last parameter). I have defined the signature as follows:
    _declspec (dllexport) uint8_t readDoubleArray(uint8_t handle, LStrHandle lPath, int64_t startTime,
    int64_t endTime, DblArrHdl *values, LongArrHdl *timebase);
    Where DblArrHdl is
    typedef struct {
    int32_t dimSize;
    double doubles[1];
    } DblArr;
    typedef DblArr **DblArrHdl;
    In the invocation I read doubles from a database, and resize the double array as follows:
    int size = doubleArray.size();
    if (NumericArrayResize(0x0A, 1, (UHandle*)values, size) != noErr) {
    setLastError(MG_ERR_LABVIEW_ERROR, "Failed to allocate memory");
    return FALSE;
     I set the size, and copy the values:
    (**values)->dimSize = size;
    for (int i = 0; i < size; i++) {
    (**values)->doubles[i] = doubleArray[i];
    When I use the DbgPrintF to validate the values it gives me a value around 120000 which is correct. However, when returned by labview the array contains strange data, like 5.38564E-315. Here is print out of the 'values' array after it has been through the DLL:
    Here is how I wired it, ignore the clustering, it occurs in the array of values which exits the DLL call.
    I have no idea how this can be. I followed the examples on the site. I also tried the normal DSSetHandleSize, but it didn't change anything. Any idea what I did wrong?
    Thanks in advance,
    Vincent
    Message Edited by DaVince on 10-22-2008 10:10 AM
    Solved!
    Go to Solution.
    Attachments:
    doubleArrayWeird.png ‏7 KB
    wireUpDoubles.png ‏18 KB

    You're right, this not directly described...  
    First you should read how LabVIEW stores data in memory,
    then read about structure packing pragma,
    and finally take a look to C/C++ preprocessor reference,
    then you will get feeling how to solve this problem...
    Otherwise own DLLs used in LabVIEW code pretty rarely, and Double precision also not very often...
    The same trouble you may get with clusters, but here behaviour described:
    "...The memory layout of a cluster depends on the platform you are running. LabVIEW may add padding between cluster elements so that those elements are aligned to certain address boundaries. Address boundaries relate to the concept of natural alignment. A piece of data is aligned on its natural boundary if the address at which it begins is a multiple of the size of the data. For example, a 4-byte integer is aligned naturally if it begins at an address which is a multiple of four. Most compilers have an upper limit on this boundary at which the restriction is relaxed. For instance, an 8-byte integer may be aligned on a 4-byte boundary. For the platforms on which LabVIEW runs, the alignment constraints are as follows:
    (Windows) Data is aligned only to 1-byte boundaries.
    (Mac OS and Linux) Data is aligned naturally up to 4-byte boundaries.
    (VxWorks PowerPC) Data is aligned naturally up to 8-byte boundaries.
    On all platforms, clusters adopt the alignment of their most restrictively aligned element..."
    best regards and happy wiring...
    Andrey.
    Message Edited by Andrey Dmitriev on 10-23-2008 03:38 PM

  • How can I resize an array of strings?

    I'm having a problem of not being able to use the CIN functions and therefore can't use the convenient resizing methods. I have tried to use NumericArrayResize to resize an array of strings, but it's not working correctly. Here's what I've tried most recently. I have tried many variations, so if you want to modify what I have posted, or just provide new code, please feel free.
    typedef struct {
    int32 dimSize;
    LStrHandle elt[1];
    } LStrHandleArray;
    typedef LStrHandleArray **LStrHandleArrayHandle;
    void someMethod(LStrHandleArrayHandle arrayOut) {
    // attempting to write the string "asdf" in the first element in the array. (1D array)
    int newSize = 1;
    MgErr e = NumericArrayResize(uL, 1L, (UHandle*)&arr
    ayOut, newSize);
    (*arrayOut)->dimSize = newSize;
    LStrHandle hdl = *(*arrayOut)->elt;
    long str_size = strlen("asdf");
    MgErr err = NumericArrayResize(uB, 1L,(UHandle *)&hdl, str_size);
    LStrLen(*hdl) = str_size;
    MoveBlock("asdf", LStrBuf(*hdl), str_size);
    The code above doesn't result in crashing labview at any time. The string "asdf" is not copied though. And, after being able to copy one string I would like to extend this to many elements in a 1D array of strings.
    Thanks!
    Naveen

    LabVIEW stores string arrays as an array of handles to those strings. To resize an array of strings you need to declare a new string in LabVIEW's data space, resize the handle array, and add a handle to your new string. Here is an example program which does this.
    -Aaron Marks
    National Instruments
    Attachments:
    resize.zip ‏252 KB

  • Resizeing an array of LStrHandles within Call Library Functio Node crashes SubVI.

    Hello,
    I try to resize an array of LStrHandles within a shared library. Here the C-code - attached a picture of the calling SubVI:
    /* Call Library source file */
    #include <stdio.h>
    #include "extcode.h"
    /* Typedefs */
    typedef struct {
            long dimSize;
            LStrHandle elt[1];
            } TD1;
    typedef TD1 **TD1Hdl;
    long strArray(TD1Hdl arg1);
    long strArray(TD1Hdl arg1)
            long err=0, count=2;
            err = DSSetHandleSize((UHandle)arg1, sizeof(long) + count*sizeof(LStrHandle));
            if(err) {
                    printf("ERROR: 'DSSetHandleSize()': %ld\n", err);
                    return err;
            (*arg1)->dimSize = (*arg1)->dimSize;
            return noErr;
    I know there are a lot of threads, I read some and also tried the provided source code but somehow LabVIEW crashes. I don't know if it is valueable but when I change the following line it does not crash:
    (*arg1)->dimSize = (*arg1)->dimSize;
    Thanks for any help,
    Johannes
    OS: RedHat
    LV: 8.2 Prof
    Message Edited by [email protected] on 03-11-2009 12:26 PM
    Solved!
    Go to Solution.
    Attachments:
    subvi-resize-stringarray.jpg ‏7 KB

    To be honest I'm not fully sure why that would crash but proper dealing is a lot more complicated than what you have done. The crash probably happens not in the C fucntion but on return of the function as LabVIEW tries to display the data. DSSetHandleSize() does not initialize the area it allocates additionally so there is likely garbage which LabVIEW then tries to interpret as string handles and consequently crashes.
    You should also use NumericArrayResize() whenever possible as it takes care of various complications that can be hard to deal with on multi platform programs. NumericArrayResize() does use internally DSSetHSzClr() which initializes additional memory to 0. That would avoid the crash since LabVIEW does interpret NULL handles as the default for the according datatype, which would be here an empty string.
    #include "extcode.h"
    #if  IsOpSystem64Bit
    #define uPtr uQ
    #else
    #define uPtr uL
    #endif
    typedef struct {
        int32 dimSize;
        LStrHandle elm[1];
    } TDStrArr, **TDStrArrHdl;
    MgErr MyArrayFunc(TDStrArrHdl arr)
        int32 count = 4;
        LStrHandle p;
        MgErr err = noErr;
        /* The array could be non empty so dispose of any elements in it that are bigger than what we need */
        for (i = (*arr)->dimSize - 1; i >= count; i--)
          p = (*arr)->elm[i];
          if (p)
            DSDisposeHandle(p)
        (*arr)->dimSize = i + 1;
        /* resize the array handle to get enough space */
        err = NumericArrayResize(uPtr, 1, (UHandle*)&arr, count);
        if (err)
          return err;
        /* Fill in the data as desired */
        for (i = 0; !err && i < count; i++)
          p = (*arr)->elm[i];
    #if !complicated
          err = NumericArrayResize(uB, 1, (UHandle*)&p, 1);
    #else
          if (p)
            err = DSSetHSzClr(p, sizeof(int32));
          else
            p = DSNewHClr(sizeof(int32));
            if (p)
              (*arr)->elm[i] = p;
            else
              err = mFullErr;
    #endif
          if (!err)
            err = LStrPrintf(p, "%ld", i);
        (*arr)->dimSize = i;
        return err;
    Rolf Kalbermatter
    Message Edited by rolfk on 03-11-2009 08:40 PM
    Rolf Kalbermatter
    CIT Engineering Netherlands
    a division of Test & Measurement Solutions

  • Cluster array to c structure in DLL

    Hello,
    I have a problem which I am stuck at so I would really appreciate any help.
    I have this function that i need to access in Labview.
    ViStatus _VI_FUNC Ki_GetSystemInfo (ViSession instrumentHandle,
    void *systemInfo);
    Now the structure for systeminfo is as follows:
    typedef struct _SYSTEM_INFO
    char pchModelNum[MODEL_NUM_LEN];
    char pchSerialNum[SERIAL_NUM_LEN];
    char pchSysSoftwareVer[SOFTVER_LEN];
    char pchPlatformVer[PLATVER_LEN];
    char pchOpSystemVer[SYSTVER_LEN];
    int bCardType[MAX_SLOTS]; // Enum slot_types
    } systeminfo;
    When i use the call Library Node function to access the above function what
    should be mine
    input and out paramteres. I tries making cluster of 5 st
    rings and an array
    of integers
    It doesnt seem to work. Any help shall be appreciated.
    Premal

    Hi Premal,
    Try to use arrays of [U8] instead of strings. Also, pay attention to INT - is OS dependent (assuming that you are using win9x/NT/2000, use [I32]). If you try with strings, be sure that the input string contains enough characters to store the result.
    Hope this helps
    p.s.: take a look on those articles mentioned in "cluster array to c structure in DLL" [http://exchange.ni.com/servlet/ProcessRequest?RHIVEID=101&RPAGEID=137&HOID=506500000005000000C05C0000&HTHREAD=000023744&UCATEGORY_0=_49_%24_6_&UCATEGORY_S=0]

  • Pro*C: Getting array of structs from a PL/SQL procedure

    I am trying to create a stored procedure that will take the results of a select query, put them into an array of structures and send the entire array of structs back to the calling function in the C program.
    I currently do a select into a cursor and return each row one at a time over the network.
    Any syntax suggestions would be of help.
    null

    I am trying to create a stored procedure that will take the results of a select query, put them into an array of structures and send the entire array of structs back to the calling function in the C program.
    I currently do a select into a cursor and return each row one at a time over the network.
    Any syntax suggestions would be of help.
    null

Maybe you are looking for