G#

cancel
Showing results for 
Search instead for 
Did you mean: 

Making the "G# Dependency injection using default constructor" example work in built app.

Hi,

I'm trying to make the G# example called "G# Dependency injection using default constructor" work after the build. The example works fine in debug mode, but after having made a built specification and built the app, it doesn't work and gives me this kind of error

Infos sur le fichier/répertoire dans G#Object.lvclass:G#Object_GetClassType.vi->G#Objec​t.lvclass:G#Object_GenericDefaultConstructor.vi:1-​>G# - DependencyInjectionUsingDefaultConstructor.vi<APPE​ND>
C:\temp\testDILV\Application.exe\1abvi3w\examples\​AddQ\G#\CreateDestroy\MyG#SubClass_class\MyG#SubCl​ass.lvclass

So it seems that he cannot find the path, but the path is given by the G#Object_GetClassPath vi, so it should be correct. It returns the path in the form C:\temp\testDILV\Application.exe\1abvi3w\examples\​AddQ\G#\CreateDestroy\MyG#SubClass_class\MyG#SubCl​ass.lvclass but G#Object_GenericDefaultConstructor doesn't seem to find it and crashes.

Is there something I'm doing wrong? Maybe in the build specification?

0 Kudos
Message 1 of 31
(16,849 Views)

Hi,

Dependency injection and building exe is always a challange. I suppose you have included all your classes that it needs inside the exe? I'm not sure that you actually can use dependency injection in that situation and that LabVIEW actually supports that. G# simply uses the native GetLVClassDefaultValue VI for this.

What you can do is to make the build specification not to include all the classes inside the exe, but force them outside by setting up a new destination what preserves disc hierarchy. Then you should be able to inject them with the path. But, you will probably have another problem now, since the location of the lvclass differs from your development environment. When I use dependency injection, I always make force the build script to keep folder structure to make sure my relative paths always will match. Then only the root folder of the development environment needs to be changed to the build exe will output.

Mattias E

AddQ

0 Kudos
Message 2 of 31
(13,467 Views)

Hello Mattias,


Thanks for your answer, unfortunately I'm not sure I understood everything.

I'm trying to use the dependency injection pattern in my own app but, seeing that it wasn't working as I expected, I tried through the "Dependency injection using default constructor" example in the G# library. Basically, I added a build specification, left most of the things by default and tried to build. From there I saw that I have the same kind of trouble I was experiencing in my own app, Labview complaining that he cannot find the .lvclass.

I think (but not 100% sure) that all classes needed should be included inside the exe. I have tried putting "MyG#SubClass.lvclass" in the "Always included" menu inside "Source Files", and in the build log I have indeed this file listed in the [Source Files] tag. In the Source File Settings I have set the destination for the .lvclass as "Application.exe".

Is there a way to "explore" the content of an exe and see the class included with their path?

I have also tried unchecking the "Remove unused polymorphic VI instances" and "Remove unused members of project libraries" but no change.

You say that you force the build scrit to keep the folder structure, where do you set this?

I don't like the option of forcing the classes outside the exe, because then they would be easily readable by users which is something I don't want. It would also complicate the deployment but that's less of an issue.

0 Kudos
Message 3 of 31
(13,467 Views)

Hi,

I attached the dependecy injection project with an additional build for exe where I put the classes outside the exe. I do believe this is the only way using dependency injection in LabVIEW due to the limitation of the GetLVClassDefaultValue functionallity.

Build and run the application and it works. You can see the details inside the build script. I will include this build script in the example in the next release of G# Framework.

Thanks,

Mattias

Message 4 of 31
(13,467 Views)

Dear Mattias,

I suspect that it is a bug in the G# vi "G#Object_GetClassType.vi" that prevents its proper functioning for classes residing within executables. To check if the class exists you use the Labview function called "File/Directory Info". In the positive case the code proceeds generating the class default value from the path, otherwise it skips it. The problem is that that Labview function is not meant to be used for files within an executable (the help just say says not with an llb, but just see here http://thinkinging.com/2009/10/02/how-to-list-files-in-a-labview-2009-executable-app/). If you diagram disable that Labview function everything goes fine. Actually it seems that the use of this function to check if the class file exists is redundant. With or without it the "G#Object_GetClassType.vi" will spit a Not a Refnum and an error 7 when the class file doesn't exist.

So I guess that it is just safe to remove that function

Cheers and thanks for your wonderful work

Andrea

0 Kudos
Message 5 of 31
(13,467 Views)

Hi Andrea!

The "File/Directory Info"  was added because LV2013 pops a dialog instead of returning an error. So we needed an easy way to check if the file exists before that dialog would pop.


We are developing a large scale application using lots of dependency injection and distributing this as an exe and installer and have not seen an issue with that funcion. That function will reside inside the exe, but will (in our case) list files outside the exe-file. I will contemplate a bit on the case where you want to pack classes inside the exe.

//Thomas

Certified LabVIEW Architect
0 Kudos
Message 6 of 31
(13,467 Views)

Hello Thomas,

I continued on the test Andrea did and it seems that LV pops a dialog instead of returning an error because you have set the option of "Get LV Class Default Value VI" with the flag "0x10" that specifically asks him to do that ("Prompt user to find missing dependent VIs or libraries of the referenced class."). If you remove that "0x10" flag you'll have, I think, the same behavior as with the "File/Directory Info" but without the problem with the file inside the exe.

Xavier

Message 7 of 31
(13,467 Views)

Thanks for seeing that Gimly. I made a fix for LV2013 and that was implemented into G#. I am not sure why option 0x10 is there, but Mattias will surely have an answer. However, our problem was that in 2013, the user will be prompted if the file specified in "class path" is not found, not only if the dependencies or a library is not found. That seems to be new behaviour. I dont have any other LV version installed on the PC I'm on right now to test.

Certified LabVIEW Architect
0 Kudos
Message 8 of 31
(13,467 Views)

Hi,

Interesting discussion. I can't really remember the exact reason for the 0x10 flag, but G# was originally developed in LV2009, so behaviour might have changed. I remember dealing quite a lot with this issue. However, it is correct that the newly introduced FileInfo prevents from running inside a exe, I just tested that. I was wrong in my previous answer regardning this. Shame on me...

It is an unwanted sideeffect I must admit using the FileInfo to compensate for the new behaviour in LV2013 regarding exe. I have a suggestion for a new implementation without removing the 0x10 flag, since if I remember correctly is quite good to set this flag if there are missing dependencies for the injected class. I don't have access to LV2013 from where I am now, so I must investigate this further later.

I attach the updated example project with two build scrips, one with the classes inside the exe and one with the classes outside. Both works now if you replace the G#Object_GetClassType.vi with the one attached. See screenshot below.

GetClassType.jpg

There is however one thing to consider then including the classes in the exe file and that it can be quite difficult to specify the class path inside exe unless you browse it as Andrea suggest above. If you for example put the injection class paths in a configuration file, it will be quite difficult to make it correct when changing between development and a built exe. Need some "smart" way to check the runtime environment to calculate the path. With an external class structure, it will be easier, but not one big nice exe.

If everyone accept this solution, I will include it in the next release, unless I find a better way using the flag options in LV2013.

Thanks,

Mattias

Download All
0 Kudos
Message 9 of 31
(13,467 Views)

It won't work for LV2013 EXE.

Certified LabVIEW Architect
0 Kudos
Message 10 of 31
(13,467 Views)