LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

vxworks: LabView LStrHandle structure

Solved!
Go to solution

Hi all!

I want to receive a cluster from vxworks to LabView.

Is it possible only when Cluster->String initialized?

It is seems code "c->s = (LStrHandle)malloc(sizeof(void*));" is incomplete. LabView requires something else. But what does LabView require?

 

CODE:
#include <string.h>
#include <assert.h>
#include <stdlib.h>

typedef unsigned long int32;
typedef char Char;

/* Long Pascal-style string types. */
typedef struct {
    int32    cnt;        /* number of bytes that follow */
    Char    str[1];        /* cnt bytes */
} LStr, *LStrPtr, **LStrHandle;

typedef struct
{
    LStrHandle s;
} Cluster;

extern "C" void changeStr(Cluster * c, LStrHandle lvs)
{
    // does not work
    c->s = (LStrHandle)malloc(sizeof(void*));
    *c->s = (LStrPtr)malloc(10);
    (*c->s)->cnt=3;
    strcpy((*c->s)->str,"bad");

    // works
    *lvs = (LStrPtr)malloc(10);
    (*lvs)->cnt=6;
    strcpy((*lvs)->str,"works!");
   
    return;
}
vxvcs.jpg
0 Kudos
Message 1 of 12
(5,089 Views)

I will ask more concretely.

LabView passes to C-code not NULL LStrHandle even if the string is empty. But when the string in a cluster, LabView pass NULL LStrHandle when string is empty.

WHY? How to work with NULL-pointer handle?

 

Message Edited by kolan on 02-26-2010 09:15 AM
0 Kudos
Message 2 of 12
(5,071 Views)
In other words, is there any way to implement NumericArrayResize function on vxworks?
0 Kudos
Message 3 of 12
(5,057 Views)

So the problem come to implement DSNewHandle(size_t)...

I will post the solution if I will found it...

0 Kudos
Message 4 of 12
(5,043 Views)

Your problem is trivial and shows a certain lack of C programming knowledge.

 

 

Take this prototype:

 

MgErr MyFuncPassByValue(LStrHandle lstr);

 

There is no way LabVIEW can pass a NULL handle into the function if the function has to be able to return a valid handle since only parameters passed by reference can be returned. So LabVIEW allocates an empty handle (a handle pointing to a memory area that contains the array dimension size 0, but no other data) and passes that to the function. The C function can now resize the handle as needed and return information.

 

MgErr MyFuncPassByReference(LStrHandle *plstr);

 

Now the handle is passed by reference and LabVIEW can and will pass a NULL handle to the function if it is empty, since it internally does use NULL handles for empty arrays and strings to save both on memory and performance as allocating an empty handle requires almost as much CPU than allocating a large one and also adds to memory defragmentation.

 

A handle embedded in a cluster is technically also passed by reference and therefore LabVIEW will not do any extra work and simply pass the NULL handle to the function too.

 

And your use of malloc to allocate a LabVIEW handle is simply outright wrong. malloc allocates a C runtime memory block not a LabVIEW handle. In order for LabVIEW to be able to work with the handles you MUST use LabVIEW memory manager functions as described in the External Code Reference manual whenever you allocate, reallocate, resize or deallocate LabVIEW handles and pointers.

Message Edited by rolfk on 03-01-2010 09:53 AM
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 5 of 12
(5,019 Views)
Solution
Accepted by topic author kolan

kolan wrote:
In other words, is there any way to implement NumericArrayResize function on vxworks?

Why do you want to implement NumericArrayResize on vxWorks? This function is provided by the LabVIEW runtime kernel and you can simply call it from your own C code.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 6 of 12
(5,016 Views)

Dear Rolf Kalbermatter! You have sad me nothing new. That's for the first. Don't resent, please.

For the second, You can try to pass a cluster with an empty string to the CompatRIO and return non empty string back. I'll be surprised to see a working example in Your next post.

And finally can You teach me how to call LabVIEW's runtime kernel function from the VxWorks, which is completely different OS on a different computer compiled with a different (gcc's child)compilator. I'll be surprised twice.

 

And a couple of words about this topic : You say that don't understand what is it. I'll explain step by step. I suppose You are a window's User (and a pinguin is just an icon 😃 and have LabView&CVI installed, so press <Win+R> and insert line below:

notepad "%Program Files%\National Instruments\LabVIEW 2009\CCodeGen\libsrc\lvanalysis\arrresize.c"

Then press `Enter`, <Ctrl+F>, insert "NumericArrayResize" string to a form  and You will see a very buggy C-code on Your computer.

 

This part of the code shows that if *ap (Value of the pointer to the Handle which means Handle's value) is a NULL, function returns an error.

if (! *ap) return mgArgErr;

But below NI's developer checks it for the NULL value again and think that memory will be allocated for the handle but We know that this part of the code will be executed never thanks for the chekup above.

if (n == 0 && *ap == NULL) {                                 

    *ap = (UHandle)DSNewHClr( (size_t)(nd * sizeof(int32)) );
    if (! *ap) {                                            
        SetError(kArresizeModNum, kMemFail);                
        return mFullErr;                                    
    }                                                       
    return noErr;                                           
}                                                            

 

 

I don't make accent on this:

p = **ap;
arr =(int32 *)p; 

And this

if ((dt == doubleDataType || dt == cmplx128DataType) && (nd % 2)) {
  newSize += 4; //allow for 8 byte alignment of doubles
}

 

code because of both parts are offtopic, but the last one is a real lack of C programming knowledge.

 


I suppose but not prove that in CVI and LabView this code has 2 compiled binary instances. And one of them was fixed (in CVI).

Perhaps my bad english can affront somebody, please know that I don't want to do this...

 

Message Edited by kolan on 03-01-2010 01:30 PM
0 Kudos
Message 7 of 12
(4,991 Views)

No I'm not only a Windows user although I mainly develop on Windows. I have written libraries such as the OpenG lvzip library that is multiplatform and incidentially even ported it to the vxWorks environment. Although I had not a CompactRIO system available to test it myself I have reports from users that it does indeed work. One C module in lvzip does use LabVIEW manager functions although not NumericArrayResize(), so I know that simply by making the correct Makefile for the VxWorks gcc compiler one can create a shared library that compiles and runs on VxWorks while using LabVIEW runtime functions.

 

I have installed LabWindwos CVI but not 9.0 and also not LabVIEW 2009 yet since I use this computer for active project development and can't risk destroying my existing and fully working LabVIEW 7.1.1, 8.2.1, 8.5.1 and 8.6.1 versions on this machine.

 

The implementation of arrresize.c you show is not availalbe on my computer but just because it is there like that does not mean that it has to be buggy. The CCodeGen part in LabVIEW was up until now limited to use for Embedded targets. VxWorks on CompactRIO is in that sense not an embedded target but a realtime target. NI has created a runtime kernel for those targets that is much more similar to the desktop runtime systems than what an embedded target ever could be.It doesn't surprise me that they to not install the full source code to the actual runtime kernel for their embedded targets but only a slimmed down version for the needs they do have on those systems.

 

Maybe CompactRIO in LabVIEW 2009 is treated indeed entirely different than in previous versions rather as an embedded target than a realtime target but I somehow doubt that since I have it from NI support that nothing has changed in terms of  VxWorks support for their realtime target between LabVIEW 8.6 and 2009 when inquiring if users might have to expect troubles when using the lvzip library in this version on CompatRIO and other NI PPC realtime targets.

Message Edited by rolfk on 03-01-2010 10:44 PM
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 8 of 12
(4,976 Views)

and runs on VxWorks while using LabVIEW runtime functions

It is a good idea, thanks! I'have not understand Your previous post above at first:

 This function is provided by the LabVIEW runtime kernel and you can simply call it from your own C code.

Now obscurity retreat. You mean that LabVIEW's runtime on vxworks compiled with gcc and it is possible to call it's functions on the same target.

 

NI's arrresize.c file for embedded systems is in attachment.When I've seen it I have assumed that such errors can be in other places and when mylib.out:function returns LabView reallocate the handler etc... But LabView uses it's own allocator and don't understand MyHandle{ulong,void*}.

 

So I've solved the problem by creating function which calculate a number and structure of handlers, then labview allocates memory for this handlers, and then like in the second attach example.

 

So Your idea with labview runtime adding to the Makefile is better. I can not step out from intended plan and must complete the work urgently. After that I hope I'll rewrite Makefile, post it here and mark the topic as "solved".

Download All
0 Kudos
Message 9 of 12
(4,952 Views)

I'm a stupid, Rolf Kalbermatter 😃

NumericArrayResize() function works on VxWorks as You say.

 

As for the CCodeGen's arrresize.c I think it is a different theme which concern other sphere.

 

Rolf Kalbermatter, Thanks a lot!

Message Edited by kolan on 03-02-2010 07:50 AM
0 Kudos
Message 10 of 12
(4,942 Views)