It assumes SB is the host and loading the COM as an extension.
Exactly. By design, SBCOM is the opposite of what you seem to be trying to implement.
I may use the threaded option for MODULE objects like IUP ...
Why would you ever need to run multiple IUP threads (i.e. IUP instances) in the first place?
Here's a typical example of a (CUI or GUI) application that may benefit from running multi-threaded.
Suppose we have an array of 600,000 reals and we need to know the total of their square roots.
(I'm deliberately choosing the data types and arith operations that would take the interpreter rather long to execute, to be able to benchmark the example and see the difference)A naive and brute force approach would be to For/Next through the entire array, take the square roots of its elements, and increment their total. But the time it would take the interpreter to complete the maths will probably be on the order of 60 seconds or more even if the loop is tight and wouldn't try to do anything else, e.g. print a [........] progress or [\|/-\|/-] spinner or pop up their GUI equivalents. Approx. 10 seconds after the loop starts, Windows is going to report your application as frozen and unresponsive, and kill it.
A wiser approach will be to let the main thread WaitForMultipleObjects() graciously (i.e. notifying Windows the thread is idling for a purpose), spawn 6 worker threads (assuming you have a 4 core Intel CPU) each to run the calc for 100,000 array elements and store the sum e.g. in element (0) of their respective array segments, and let the 8th thread print or roll the spinner.
When all the 6 worker threads are through, the main thread would wake up, kill the remaining 8th thread that's been running the spinner, and calc the final total iterating through the 6 intermediate accumulator elements at array indices (0), (100000), (200000), ..., (500000).
Et voila! You're going to reach your objective approx. 5 times faster than single-threaded (thread context switches take their toll so the time gain will always be lower than expected), and Windows isn't going to kill your app because using the WaitForMultipleObjects() system API has made it aware the application's been fully active all that time.
Unless you can draw up a similar analysis of your projected MT OCX use cases where your application(s) can benefit from running in a multi-threaded mode, you probably don't need MT at all.
Unless Mike has an idea how an OCX interface for SB can be created ...
If SB remains the host and the user control DLL is written in C/CPP with a flat API interface, then their interop should be implemented exactly as the one between SB and any other DLL, i.e. via DLLC. If the user control DLL is in fact a COM aware OCX and the program logic is built around COM objects, then the OCX should also have a flat API interface (like ProvideX) because SB cannot provide and accept COM objects directly as it doesn't have its own COM-compatible variant data management engine. The implementation should then resemble that of SBCOM with the means to fully and graciously handle COM variant creation/destruction added.
(SBCOM uses a simplified scheme that precludes clean handling of variants because the server and client create their respective variants in different memory spaces. Currently its client and server COM variants cannot be safely managed (i.e. released/destroyed as needed) on the opposite side -- only on the side where they've been created)Until you sort out the design and logical structure of the interop you want to implement, Mike won't have the slightest idea of how to implement such an interface and whether OCXes are needed for it at all, in the first place.