Author Topic: SBOCX  (Read 11235 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
SBOCX
« on: January 16, 2019, 09:37:53 PM »
Mike,

If I load an OCX with a SB script, can another OLE process connect to the OCX and have it callback to a SB function. Nothing visuall, just a OLE SB interface.

I don't see this much different than Sage's PVXCOM OLE interface to the language.

The cool part is SB could run out of a DLL. (libscriba) MODULEs could be objects created as SBT threads.
« Last Edit: January 16, 2019, 10:57:14 PM by John »

Mike Lobanovsky

  • Guest
Re: SBOCX
« Reply #1 on: January 17, 2019, 02:24:47 AM »
For all intents and purposes, an OCX is just a DLL which means its single disk copy can be reused concurrently by an infinite number of memory images in an infinite number of processes, each image for its own purpose. However that also means that interprocess communication restrictions apply.

A COM-aware DLL (OCX) is an inproc (in-process) server, and though it is theoretically possible to set up a common "shared" memory store for numeric values through the DLL, the trick won't work for handles or pointers to objects, UDTs, strings, functions, etc. because each process has its own address space whose pointer values are meaningless for another concurrent process. Thus generally speaking, you can't use the DLL for interprocess communication.

OTOH if a call to an SB callback is programmed within the OCX as a means to implement some of its particular functionalities, then the scheme will most likely work if SB is compiled as a DLL as well. It will then be mapped into the memory space of the process that's calling the "parent" OCX.

(Why not use an SB specific thread for such a question, John?)

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #2 on: January 17, 2019, 09:08:05 AM »
Thanks Mike!

I'll try putting a proof of concept together and get a copy to you. I think the idea has a lot of merit.

MT will be the shared memory means of communication. SB as a COM OLE OCX running in a thread safe model could make the language more attractive under Windows 32 bit.

I will clean  up this thread today.
« Last Edit: January 17, 2019, 12:17:45 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #3 on: January 17, 2019, 07:23:20 PM »
For some reason my SBT extension module is segment faulting under Ubuntu 18.10. I rebuilt the extension module (no errors) and it still does the same.  :-[

I'll give it a try under Windows 7 which is where is going to run anyway. I confused why my Linux version of SBT no long works.
« Last Edit: January 17, 2019, 07:25:22 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #4 on: January 17, 2019, 07:48:54 PM »
Works great under Windows.

This is a quick proof of concept for the SBOCX control. Script BASIC would be loaded by the OCX and the worker script creates threads for object MODULEs. The main SB process can call functions/subs (METHODS) and access global variables not defined with the LOCAL keyword. (PROPERTIES)


This example is like doing a RUN in other interpretive BASIC languages. With SB you can load the script without running it, run it multiple times and clearing or leaving the variables as is with the next run command.

Code: ScriptBasic
  1. ' SBOCX Proof of Concept
  2.  
  3. IMPORT sbt.sbi
  4.  
  5. sb_code = """
  6. MODULE JRS
  7. FUNCTION prtvars(a, b, c)
  8.  PRINT a,"\\n"
  9.  PRINT FORMAT("%g\\n", b)
  10.  PRINT c,"\\n"
  11.  prtvars = "Function Return"
  12. END FUNCTION
  13.  
  14. a = 0
  15. b = 0
  16. c = ""
  17.  
  18. END MODULE
  19. """
  20.  
  21. sb = SB_New()
  22. SB_Configure sb, "C:/Windows/SCRIBA.INI"
  23. SB_Loadstr sb, sb_code
  24. SB_NoRun sb
  25. ' Call function before running script
  26. funcrtn = SB_CallSubArgs(sb,"jrs::prtvars", 123, 1.23, "One, Two, Three")
  27. PRINT funcrtn,"\n"
  28. ' Run script initializing globals
  29. SB_Run sb, ""
  30. ' Assign variables values
  31. SB_SetInt sb, "jrs::a", 321
  32. SB_SetDbl sb, "jrs::b", 32.1
  33. SB_SetStr sb, "jrs::c", "Three,Two,One"
  34. ' Call function again with variables assigned in the previous step
  35. SB_CallSubArgs sb, "jrs::prtvars", _
  36.           SB_GetVar(sb, "jrs::a"), _
  37.           SB_GetVar(sb, "jrs::b"), _
  38.           SB_GetVar(sb, "jrs::c")
  39. SB_Destroy sb
  40.  


C:\ScriptBASIC\examples>scriba sbt_module.sb
123
1.23
One, Two, Three
Function Return
321
32.1
Three,Two,One

C:\ScriptBASIC\examples>



This example is running the script as a self running thread. The main SB process can still make calls and return global variables like the run example above. The MT extension module can be used to post status info to R/W lockable shared memory space.

Code: ScriptBasic
  1. IMPORT sbt.sbi
  2.  
  3. sb = SB_ThreadStart("tcall.sb",undef,"C:\\Windows\\SCRIBA.INI")
  4. SB_SetInt sb, "main::a", 123
  5. SB_SetDbl sb, "main::b", 1.23
  6. SB_SetStr sb, "main::c", "One, Two, Three"
  7. funcrtn = SB_CallSubArgs(sb, "main::prtvars", _
  8.           SB_GetVar(sb, "main::a"), _
  9.           SB_GetVar(sb, "main::b"), _
  10.           SB_GetVar(sb, "main::c"))      
  11. PRINT funcrtn,"\n"
  12. SB_Destroy sb
  13.  

Code: ScriptBasic
  1. FUNCTION prtvars(a, b, c)    
  2.   PRINT a,"\n"              
  3.   PRINT FORMAT("%g\n", b)  
  4.   PRINT c,"\n"              
  5.   prtvars = "Function Return"
  6. END FUNCTION                
  7.                              
  8. a = 0                        
  9. b = 0                        
  10. c = ""                      
  11.  


C:\ScriptBASIC\examples>scriba t_thread.sb
123
1.23
One, Two, Three
Function Return

C:\ScriptBASIC\examples>


« Last Edit: January 17, 2019, 08:38:48 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #5 on: January 17, 2019, 10:59:57 PM »
This example shows that SB is truly running in a theaded model.

Code: ScriptBasic
  1. ' SBT Main
  2.  
  3. IMPORT sbt.sbi
  4.  
  5. SB_ThreadStart("sbt_thread.sb", "1","C:/Windows/SCRIBA.INI")
  6. SB_ThreadStart("sbt_thread.sb", "2","C:/Windows/SCRIBA.INI")
  7. SB_ThreadStart("sbt_thread.sb", "3","C:/Windows/SCRIBA.INI")
  8.  
  9. FOR x = 1 TO 10
  10.   PRINT "Main: ",x,"\n"
  11.   sb_msSleep(10)
  12. NEXT
  13.  
  14. SLEEP(2)
  15.  

Code: ScriptBasic
  1. ' SBT Thread
  2.  
  3. IMPORT sbt.sbi
  4.  
  5. tnum = COMMAND()
  6.  
  7. FOR x = 1 TO 10
  8.   PRINT "T-" & tnum," : ",x,"\n"
  9.   SB_msSleep(10)
  10. NEXT
  11.  
  12. SB_ThreadEnd
  13.  


C:\ScriptBASIC\examples>scriba sbt_main.sb
T-1 : 1
T-2 : 1
T-1 : 2
T-2 : 2
T-3 : 1
Main: 1
T-2 : 3
T-1 : 3
T-3 : 2
Main: 2
T-1 : 4
T-2 : 4
T-3 : 3
Main: 3
T-2 : 5
T-1 : 5
T-3 : 4
Main: 4
T-1 : 6
T-2 : 6
T-3 : 5
Main: 5
T-2 : 7
T-1 : 7
T-3 : 6
Main: 6
T-1 : 8
T-2 : 8
T-3 : 7
Main: 7
T-2 : 9
T-1 : 9
T-3 : 8
Main: 8
T-1 : 10
T-3 : 9
T-2 : 10
Main: 9
T-3 : 10
Main: 10

C:\ScriptBASIC\examples>


« Last Edit: January 19, 2019, 06:16:22 PM by John »

Mike Lobanovsky

  • Guest
Re: SBOCX
« Reply #6 on: January 18, 2019, 03:22:23 AM »
Yes, the last printout definitely looks like a few unsync'ed  threads randomly overtaking ownership of the console buffer to print their respective output in an out-of-order fashion.

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #7 on: January 18, 2019, 09:19:59 AM »
Is that your translation of WOW?

I'm working on creating the OCX part now.

If anyone is interested and would like to follow along, the Windows 32 bit Script BASIC Inno install has the SBT extension module and a couple examples to work with.

When I'm done, SB can run in the console, as a true Windows app or as as a COM/OLE object interface callable by COM/OLE automation compliant languages and tools. Along with its original design of being an embeddable scripting engine.
« Last Edit: January 18, 2019, 02:32:24 PM by John »

Mike Lobanovsky

  • Guest
Re: SBOCX
« Reply #8 on: January 18, 2019, 03:16:04 PM »
Is that your translation of WOW?

No, that's just a statement of fact that the intermittent printout looks pretty much like the For/Next loops would look printing from known genuine threads that haven't been synchronized with mutexes, semaphores, or critical sections. I used to have a similar sample script to demonstrate FBSL Dynamic C JIT compiler's multithreading capabilities.

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #9 on: January 18, 2019, 03:21:29 PM »
You're forgiven.  :)

SBT has been a goal of mine with SB since the beginning. I knew it could be done because Peter did it with sbhttpd. It turned out better than I anticipated and the icing is it works with MT.
« Last Edit: January 18, 2019, 03:35:19 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #10 on: January 18, 2019, 07:49:39 PM »
Mike,

I took a peek at my OCX forms example code as a base to build the SB.ocx control. It looks like Dave has the SB function callback as a function in his COM extension module DLL. I have't investigated if a scriba load feature exists or not in the DLL. This may a bit more work than I anticipated but I still think it's worth the effort. I would like to get your take on doing this.

How to develop and deploy ActiveX control in C#

The SB.ocx must do the following.
  • On load of the OCX a worker instance of SB needs to be created returning it's handle as the object handle for the instance.
  • CREATE function that creates a SB thread of a MODULE returning the instance handle for the SB thread.
  • CALL SB functions (methods) in threads (MODULE objects)
  • GET / SET functions to get SB global module variables or assign them. (Properties) The SB script must declare all global variables as SB.ocx doesn't create new global SB variables.
  • DROP SB threads or the worked instance via the SB.ocx interface.



« Last Edit: January 18, 2019, 09:34:19 PM by John »

Mike Lobanovsky

  • Guest
Re: SBOCX
« Reply #11 on: January 19, 2019, 05:04:16 AM »
John,

First and foremost, please note that developing ActiveX controls in C# and deploying them is probably the last thing I'm prepared to be engaged in ATM.

Now consider the following before you put your efforts in your MT OCX venture:
  • 99% of applications presuppose a logically well-ordered sequence of actions including user interaction as needed. Therefore the sequential program flow a single-threaded application follows is ideal in order to know exactly where you are at any given point in time while the application runs. OTOH as you can see from your own printout, multiple threads run simultaneously but asynchronously, and you can't foretell which thread completes its task the first and when, and which one, the last. You can only WaitForMultipleObjects() in the main thread till all the worker threads are done with their respective tasks and then stitch their results together for subsequent use as planned.
  • Due to the asynchronous nature of threads, they are usually used to perform similar, rather than different, tasks in parallel. Different tasks (I'm talking about your various modules each running in its own thread) are usually fulfilled in a certain order. Since your main program can load as many different DLLs for different tasks as needed and execute them in a logical order of events in a single (main) thread, the use of multiple threads seems unjustified in most cases. Developing and debugging successfully a multi-threaded application is not trivial even for a highly proficient programmer.
  • The only reason to spawn a worker thread in a GUI program I can think of is to run an asynchronous spinner or progress bar whose operation should not be blocked by the tight loops in the main thread.
  • An application GUI can only be controlled by the thread that created it.
  • VB6 and its ActiveX.ocx/ActiveX.exe derivatives are not thread safe and can only run single threaded.
  • A reasonable number of concurrent threads including the main thread in order to speed up program execution is two times the number of processor cores your Intel CPU has. Launching more threads than that works but the overall performance drops even lower than in a single threaded implementation.
Proceed with your work only iff you can justify it in view of all the points I noted above, or your interest is of purely scientific nature, or it's just a challenge to test your skills.

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #12 on: January 19, 2019, 09:17:14 AM »
Quote
Proceed with your work only iff you can justify it in view of all the points I noted above, or your interest is of purely scientific nature, or it's just a challenge to test your skills.

All I'm trying to do is what you and I  just worked on with PVXCOM, only with SB not ProvideX. The C# example was just that. (how to write a OCX outside of VB) I'm all ears what you recommend using to build this OCX front end to SB.

I going to give what already works with Dave's COM extension module. The OCX isn't running multi-threaded, SB is. The OCX is just an interface.

Quote from: Karl E. Peterson
Microsoft had never rendered any of their customer's data unusable. Not once. Why they did it first to the users of the world's most popular programming language ever, the product the company was founded upon and that may have had more impact on their overall corporate position than any other, is extremely puzzling. After years neglecting the VB6 community, Microsoft seems to be missing something. Us!
« Last Edit: January 19, 2019, 10:09:10 AM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #13 on: January 19, 2019, 10:33:12 AM »
I may use the threaded option for MODULE objects like IUP that has a message loop that needs to run. Using the RUN option is more flexable and for most method calls will work fine.

I looked at the COM extension module and there isn't a means to start a SB main instance. It assumes SB is the host and loading the COM as an extension.

Unless Mike has an idea how an OCX interface for SB can be created without a lot of work, I'm going to have to be happy with where things are at on the Windows 32 bit OCX front.
« Last Edit: January 19, 2019, 02:00:00 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 3573
    • ScriptBasic Open Source Project
Re: SBOCX
« Reply #14 on: January 19, 2019, 04:38:28 PM »
I might just create an OOP extension module using the same cocepts I had with the OCX direction.