Jump to content

charlie87

Members
  • Posts

    13
  • Joined

  • Last visited

Posts posted by charlie87

  1. There is nothing new there as far as iterating the array of strings goes. Instead of a double array you basically have a string. This is a C string in the DLL and you need to MoveBlock() into a LabVIEW handle that you have allocated before with a long enough size. Using Initialize Array with a type of U8 and passing it as C array pointer into the dst parameter of MoveBlock() will do, and after the MoveBlock() call you can convert it to a string with Bytes To String.

     

    Thank you for answer. I worked it out exactly as you described. However, is there any option to do it without the string preallocation ? My C DLL function serialize some results and the the final length of the returned string is unknown....

  2. Something like this should probably work. But beware it's not tested in any way.

     

    attachicon.gifTest Array Pointers.png

     

    Thank you very much, it helped me to work it out.

     

    Anyway, the code is not working, I tested it. Another MoveBlock operation must be placed before the for loop to get the array of pointers to double arrays. Then the array of pointers is iterated in the for loop and the data of known size can be read.

    return Double Ptrs.vi

  3. Hi,

     

    rolfk, I am sorry for the bad code example. As I posted before, the myfunction is much more complex and I just wanted to show demonstration of some functionality which I am interested in. Anyway, I tryied to wrote it quickly, therefore there were some mistakes such as not freeing the arrayptrs_out or different function and variable names. One more time, sorry for that.

    Ok, I understand the reason of exporting also free_arraptrs function.

    I forgot to post that the size of double arrays which are pointed by arrayptrs_out will be know. The function returns them also, that is not any problem.

     

    I am the most interested how to get the data from the arraptrs_out to LabView array where I can work with them. If somebody may post some code example where the arrayptrs_out have e.g. one element i.e. points to one double array with e.g. 10 samples (know size) it would be great....  

  4. 
    

    This is just a code example. The final C function is more complex...

    MY_API void myfunction(double ***arrayptrs, int *size)

    {

    double testdata1[5] = {1,2,3,4,5};

    double testdata2[7] = {1,2,3,4,5,6,7};

    *size = 2;

    /*allocate the array of pointers to jagged double arrays*/

    *arrayptrs_out = (double**)malloc(*size*sizeof(double*));

    /*allocate 1st double array*/

    *arrayptrs_out[0] = (double*)malloc(5*sizeof(double));

    memcpy(*arrayptrs_out[0], testdata1, 5*sizeof(double));

    /*2nd double array*/

    *arrayptrs_out[1] = (double*)malloc(7*sizeof(double));

    memcpy(*arrayptrs_out[1], testdata2, 7*sizeof(double));

    }

    MY_API void free_arrayptrs(double **arrayptrs_out, arraycnt_out)

    {

    for(int i = 0; i < 0; i < arraycnt_out)

    {

    free(arrayptrs_out);

    arrayptrs_out = NULL;

    }

    free(arrayptrs_out) = NULL;

    arrayptrs_out = NULL;

    }

    int main(int argc, char* argv[])

    {

    double **arrayptrs_out = NULL;

    int arraycnt_out = 0;

    myfunction(&arrayptrs_out, &arraycnt_out);

    /*do something with the arrays. The size of particular element is know.*/

    free_arrayptrs(arrayptrs_out, arraycnt_out);

    reutrn 0;

    }

  5. No I do not (pre)allocate any memory. I do not know how many arrays I will have and how long the arrays will be.

     

    The 2nd paragraph:

    In the case of the function  ( void myfunction(double ***arrayptrs, int *size) ) when I am calling the dll from top level C code, I declare the arrayptrs (double **arrayptrs ) in my main().This is to be passed to a function to have memory allocated to it ( myfunction(&arrayptrs, &size) ). Then I do some operations and in the end I free the resources in the main(). Now I would like to replace the top level C code with LabView. The size parameter is an output specifying the count of the double arrays (length of the arrayptrs array)

  6. Yes, it's possible, although a bit complicated. Use moveblock to copy the array of addresses into a LabVIEW array, then iterate through those and use moveblock to copy the actual data into an array. Or, use the technique explained here: https://decibel.ni.com/content/docs/DOC-9091. You'll need to account for your arrays having different lengths, which you could do simply by bundling each one to generate an array of clusters where each cluster contains an array. 

     

    I have some problems with implementing the code based on the instruction with the MoveBlock function. My C function which returns the array of pointers to double arrays looks like: void myfunc (double ***arrayptrs, int *size). Could you provide some small example how to dereference the pointer ?

    My solution does not work..

      

  7. Yes, it's possible, although a bit complicated. Use moveblock to copy the array of addresses into a LabVIEW array, then iterate through those and use moveblock to copy the actual data into an array. Or, use the technique explained here: https://decibel.ni.com/content/docs/DOC-9091. You'll need to account for your arrays having different lengths, which you could do simply by bundling each one to generate an array of clusters where each cluster contains an array. 

    Thank you for quick answer. It makes sense. I suppose that the same should be possible when the C function returns the array of strings.

     

    I have one more question about freeing resources. As I mentioned, the C function returns an array of pointers to double arrays of different sizes. These double arrays are dynamically allocated by malloc. How to clear this memory in the end of program ? Is it possible ans safe by DisposePtr Node ? 

  8. It might work! I'm not sure about the array of pointer sized integers though. On the LabVIEW diagram they are always 64 Bits, but possiby LabVIEW does the right thing here and only converts to a 64 Bit value when passing it to an indicator. That should be indicated with a coercion dot IMO, but it isn't.

    Hi,

    I tried it also and it really works perfectly. However, I have similar issue which I am not sure how to fix it. My C dll function has an input which requires array of pointers to double array. (double** arrayptrs). Is there any option how to solve it like in the case for array of strings ? 

  9. Thank you for your answer Ned. U r right, I am not very good in C programming. Stars * are my enemy forever. Also the second part of your answer is relevant. I was able to change the values inside the DataArray (pointer) in original, therefore I was confused when I cannot do the same.

    Maybe, you can help me with another issue. I am expected do change the cluster array BufferPtr, add new elements respectively. I am trying to follow the example posted on the first page of this topic: 

    err = DSSetHSzClr(arg1, Offset(MyArray, Cluster) + sizeof(MyCluster)*numElems)

     

    I have read the specifications and some more examples, but I am not sure that I understand the meaning of the DSSetHSzClr. As I understood, the point is to increase the memory block pointed by the handle arg1. I am little bit confused, how to calculate the block size in my case. I suppose, that the Data which is part of the cluster can be variable sized as well as the strings Name and String. Do I need to calculate the size of the Buffer dynamically (count all items in DataArray and length of all strings) or not ?

  10. Hi,

    I am starting to work with array of clusters inside the C DLL. I followed your nice instructions which help me so much. However, I have problem with simple changing the integer value inside the cluster. 

     

    My cluster is defined:
     

    typedef struct {	int32_t dimSize;	double Item[1];	} DataArray;typedef DataArray **DataArrayPtr;typedef struct {	LStrHandle Name;	LStrHandle String;	int8_t Type;	DataArrayPtr Data;	} Cluster;typedef struct {	int32_t dimSize;	Cluster Variable[1];	} Buffer;typedef Buffer **BufferPtr;

    I would like to change the value of the first cluster array element Type (int8_t). Lets see my test function:

    int myfunction(BufferPtr parameters) {    Cluster var;        var = (*parameters)->Variable[0];    var.Type = 15;    return var.Type;}

    The myfunction return the value 15, however, I would expected that the value will be changed also inside the output cluster from the Call Library Function Node... But it does not...

×
×
  • Create New...

Important Information

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