Best Way to Load Externals

Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
SirWobbyTheFirst
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 239
Joined: Tue Jun 30, 2009 11:15 pm

Best Way to Load Externals

Post by SirWobbyTheFirst » Fri Mar 03, 2023 11:31 am

Hi Everyone,

I'm working on a command line app and currently have a Startup handler that pretty much carries out all execution of the application, parsing and processing command line arguments, writing to StdOut, carrying out the main application logic. One of the dependencies of the app is the XML library and I am aware that using the normal method of including it in the standalone settings, the XML library would not be available during execution of the Startup handler.

So I planned to get around this by calculating the appropriate file path for the DLL or SO and adding that to the Externals of the Template Stack before creating an invisible stack and then setting the behaviour property of my apps main stack to the newly created stack, the logic seems to make sense. But I'm finding in the standalone app, this does not work, verbose output stops right at the point when the first call to the XML library occurs and the app stays running but does not continue.

I can confirm the DLL gets loaded into the process on Windows because if I load Process Hacker and look at the modules tab, I can see the DLL get loaded from the location, so it seems to be there but no calls get carried out. Are there any quirks about loading an external during the Startup handler that I'm not aware of? Because as far as I am aware, the reason the XML library isn't available when included normally is because the supporting stack does not get loaded until after PreOpenCard has been called.

Mike

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7236
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Best Way to Load Externals

Post by jacque » Fri Mar 03, 2023 7:48 pm

Is there a reason the library needs to load on startup? Usually waiting until opencard finishes on the first card of the stack is good enough and to the user there is no difference.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

SirWobbyTheFirst
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 239
Joined: Tue Jun 30, 2009 11:15 pm

Re: Best Way to Load Externals

Post by SirWobbyTheFirst » Mon Mar 06, 2023 12:07 am

Hi Jacque,

I did some further testing and from what I can gather using an external from a behaviour stack in a standalone just flat-out does not work or it is a Standalone home stack quirk. I carried out a series of tests to confirm this:

1. I swapped from setting the behaviour property of my main stack to inserting the script of the stack with the XML library external set into the back scripts. Result: Success
2. I reverted to setting the behaviour property, renamed the Startup handler to Function AppStartup and added a PreOpenStack handler that would do a Dispatch Function "AppStartup" call. Result: Failure
3. I reverted to setting the behaviour property, renamed the Startup handler to On AppStartup and added a PreOpenStack handler that would do a Send "AppStartup" To Me In 30 Ticks call. Result: Failure
4. I reverted to setting the behaviour property, renamed the Startup handler to On AppStartup, added a PreOpenStack handler to hide the main stack, and then added an OpenStack handler that would do a Send "AppStartup" To Me In 30 Ticks call. Result: Failure.
5. I manually created a stack with the XML library attached as an External, loaded the stack into memory in the standalone, set the behavior of the main stack and then carried on with Startup like normal. Result: Failure.

But what I've found is that all five of these work fine in the IDE, the XML library is shown in the Modules tab on System Informer for the IDE and from the context of the main stack, a call to revXMLTrees() presents an empty value, which is expected and later on presents the one XML ID when the app executes, and then from the context of menubar stack or Message Box, a call to revXMLTrees() presents a list of XML IDs that the IDE's regular XML library instance has loaded from when the Dictionary has been opened for example, so the external attached to a behavior stack functionality works.

So either this is something not implemented in the standalone engine or its one of those standalone home stack quirks where because my main stack is the one the standalone engine immediately opens, this is something that doesn't happen, similar to how if you set a password on a stack and then build it as a standalone (Instead of setting a password in the standalone settings), it just displays the stack window and no execution occurs, this is something I've worked around in the past by basically building a stub loader that becomes the standalone and then everything else is loaded in from another stack.

Mike

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7236
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Best Way to Load Externals

Post by jacque » Mon Mar 06, 2023 8:21 pm

Have you tried just setting the behavior of the mainstack in its property inspector and letting the engine load it automatically? I think you need to add the behavior stack to the stackfiles list and be sure to include it in the Copy Files pane. Don't add any particular scripting to manage it, let the engine do it.

I worked with a mainstack that had dozens of script-only stacks set as behaviors and the trick seems to be adding them to the stackfiles.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

SirWobbyTheFirst
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 239
Joined: Tue Jun 30, 2009 11:15 pm

Re: Best Way to Load Externals

Post by SirWobbyTheFirst » Mon Mar 06, 2023 10:02 pm

Hi Jacque,

The behaviour itself loads fine, I added a little function that would just return the number 1 to the caller and called it from the mainstack and that is fine, but the External attached to the behaviour stack just will not have it for some reason.

Mike

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7236
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Best Way to Load Externals

Post by jacque » Tue Mar 07, 2023 7:48 pm

Is the behavior stack a script-only stack? Those do not save anything except the script text itself. The actual external would not be retained. I'm thinking it isn't script-only since your first experiment worked.

You could try adding the external to the mainstack so it would be available normally in the standalone, and continue using the behavior script itself. Or, since inserting the stack into the back works, just use that.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

SirWobbyTheFirst
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 239
Joined: Tue Jun 30, 2009 11:15 pm

Re: Best Way to Load Externals

Post by SirWobbyTheFirst » Tue Mar 07, 2023 11:39 pm

Hi Jacque,

The behaviour stack is just a stack created at runtime, it does not have a presence on disk, my main stack just creates the stack in memory, sets the Externals property to the XML library and then sets its Behavior property to the new stack. If I put the new stack into the back/front scripts or the libraries, the External is usable but if used as a behaviour it isn't even though the DLL is loaded into Windows.

I'm currently trying to work out an activation issue with LC at the moment, so I won't be able to test anything else until that's corrected by Support, so bear with me if you need me to test anything.

Mike

jacque
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 7236
Joined: Sat Apr 08, 2006 8:31 pm
Location: Minneapolis MN
Contact:

Re: Best Way to Load Externals

Post by jacque » Wed Mar 08, 2023 12:12 am

I'll be curious to hear what you find out. I'm currently having issues with an external too so maybe it's related. It works fine in the IDE but not in a standalone. I'm building for MacOS but maybe the problem is the same.
Jacqueline Landman Gay | jacque at hyperactivesw dot com
HyperActive Software | http://www.hyperactivesw.com

mwieder
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3581
Joined: Mon Jan 22, 2007 7:36 am
Location: Berkeley, CA, US
Contact:

Re: Best Way to Load Externals

Post by mwieder » Thu Mar 16, 2023 1:00 am

From memory, setting the external of a stack does set the property but it isn't activated until the next time the stack loads. So setting the external on the fly (especially a newly-created stack) without relaunching the stack won't have an effect. Probably your only way out is to have a blank substack of the main stack, set the external of the substack to the DLL, save it, and then the next time you launch the mainstack your external handlers should be available.

SirWobbyTheFirst
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 239
Joined: Tue Jun 30, 2009 11:15 pm

Re: Best Way to Load Externals

Post by SirWobbyTheFirst » Fri Mar 17, 2023 12:33 am

Hi Jacque and mwieder,

So yeah, the testing I did seems to confirm what mwieder (Is it Mark? It's been a while since I last saw your name and cannot remember it.) said. It seems the IDE does something odd in that creating a runtime stack, setting the external property for it and then setting the behaviour property to it works fine to pull in the DLL.

But the standalone engine does not, both engines work fine if you use the Start Using Stack syntax or Insert The Script Of Stack Into Back/Front syntax but only the IDE seems to support the behaviour method. Having done all these tests, I think its pretty safe to say, I know what to use for my current CLI-based application.

For another project, I make use of what I call a Platform Abstraction Library (A play on the Hardware Abstraction Library found in Windows and Linux to abstract motherboard differences) which is a stack whose sole purpose is to be linked to the DLL in question and provide some platform-specific functions to the application. For the PAL scenario, the behaviour method works every time because as mwieder states, the External is pulled in when the stack is loaded and the PAL is already linked to the DLL, Bundle, SO in question already.

But this was a fun rabbit hole to go down, apologies for the delay in responding, the licensing issue got resolved by support the next day but then I got swatted in the face by a nasty flu, so I'm just now getting back to work.

Mike

Post Reply

Return to “Talking LiveCode”