Jump to content
Zyl

Public DVR on a private class : access problems

Recommended Posts

Hi everybody,

 

I'm running into something I don't really understand. Maybe you can help me here !

I've got a LVLIB that is used as an 'Interface': it exposes public VIs which wrap around public functions of a private class (see code attached) . The class is private because I want to force the users to use the 'interface' functions.

In one of my interface VI, I create a DVR on the private class (Interface_init). The DVR is stored into a typedef (FClass_DVR.ctl) and this typedef is the 'reference' that link all the interface public functions.

In TestCode.vi (which is not part of the lvlib and illustrates the standard code that a user can create to use my driver), I can call my public interface functions and link them without any problem.

image.png.aea37ed7be49c387f7ff3d379d5b1d62.png

But as soon as I create an indicator on that reference (to create a state-machine-context-cluster for example), my TestCode VI breaks !

image.png.559823c91149cff244fbbab7664fbe9d.png

The error returned is : This VI cannot use the LabVIEW class control because of library access scope. The LabVIEW class is a private library item and can only be accessed from inside the same library or libraries contained in that library.

I understand that the class is private. But the DVR is contained into a public control. Using an In Place structure on that DVR into TestCode would not work, since the class is private. So why is the DVR control problematic at that point ? Creating it do not breaks any access protection...

Am I missing something ?

DVR Private POC.zip

Share this post


Link to post
Share on other sites

As described, anyone can take your DVR, unbundle it, and get access to the class. Since this is possible, and the class is private, it must be blocked. Technically this doesn't make much sense for labview classes since their data is private by default. Makes more sense for clusters, where enclosed data is private, so maybe thats why.

 

You can make the methods of the class private, but the class itself must be public. Or, you could use a DVR of the base labview object and then cast it when you use it, inside of your library.

Edited by smithd

Share this post


Link to post
Share on other sites

Hi!

The class itself is private (set a s private in the lvlib), so nobody with the DVR can use what's in the class outside the functions in the LVLIB.

The control containing the reference is public. IMO, I should be able to create the control outside the lvlib.

Edited by Zyl

Share this post


Link to post
Share on other sites

Remember that the DVR is a container which contains the class. Since your class is privately scoped, only library members can act on it. No terminals containing the DVR will allowed unless your class itself is accessible to the caller.

image.png.f9b69e0a3fa3c9136a46304fa0b57612.png

You can still achieve exactly what you want by moving your interface methods (DVR terminals) inside your class as public members of the class. As @smithd suggested, make all your current class members be protected (if dynamic dispatch methods) or private (for your static dispatch methods) and set your class' scope to Public. In addition, you don't need a lvlib to wrap your public interface as the class is already a library.  

image.png.b93bbadf0543dc32592a3c72b2df59ed.png

 

Share this post


Link to post
Share on other sites

Hi Francois,

I was seeing the DVR more like a 'pointer' (the address in memory) on the class, not a representation of the class itself. To me, if it is really a pointer, and the variable containing the pointer is public, I should be able to access the pointer everywhere. But of course, I wouldn't be able to use what's pointed (because it is private).

This is the way I was seing this, I am maybe far away from the truth 🙂 

Anyway, I wonder if it is the same behavior in C++ (or other OO language using pointers)....

For the 'interface' part of the problem, yes the lvclass is a lib. But I guess that originally, the code was designed to allow building a PPL. So I guess that's why the interface is in a LVLIB and it contains the lvclass.

Share this post


Link to post
Share on other sites

Doing a quick search, C++ doesn't permit access scope for the class itself -- only at the member level. In other words the class itself is always public

Share this post


Link to post
Share on other sites

 

On 8/9/2019 at 10:06 PM, Zyl said:

I was seeing the DVR more like a 'pointer' (the address in memory) on the class, not a representation of the class itself

Hi,

You can actually typecast your DVR reference to U32 value (pointer) and back. You can store this U32 number in a helper class, that will represent your API.

 

DVR Typecast.png

 

Or, if you decide to go with a helper API class, then you actually don't need to typecast it to U32 - just store the DVR inside the public API helper class:

1224355146_DVRinAPIHelperclass.png.f6bd075310589669d4a6f6586c3e216c.png

Edited by smidsy
Extending an idea with API class. You can just store the DVR inside, without typecsting. The point of my post is that DVR is actualy a pointer (u32)

Share this post


Link to post
Share on other sites
On 8/9/2019 at 3:06 PM, Zyl said:

I was seeing the DVR more like a 'pointer' (the address in memory) on the class, not a representation of the class itself. To me, if it is really a pointer, and the variable containing the pointer is public, I should be able to access the pointer everywhere. But of course, I wouldn't be able to use what's pointed (because it is private).

Even as a pointer, that wouldn't work in C++. Any use of the type in a public signature must be public, even by pointer, even by reference.

Share this post


Link to post
Share on other sites
17 hours ago, smidsy said:

You can actually typecast your DVR reference to U32 value (pointer) and back. You can store this U32 number in a helper class, that will represent your API.

I wouldn't do this. Its probably ok in this limited case, but its possible to make labview crash in this way. A better route is the variant, which has the same capabilities (cast to an opaque untyped blob and back again) but without the danger.

Share this post


Link to post
Share on other sites

DVRs can be upcast and downcast with To More Generic and To More Specific. So if you have a public type that is the ancestor of the private one, you can upcast to the public one in public and then downcast when you need to actually use it. That's all completely type safe.

(Note: DVR of LabVIEW Object works without you having to create a new ancestor class.)

Edited by Aristos Queue
  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

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

Guest
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.