Accessing C++ standard library in HSL?

Namely, is it possible and how is it done if so?

HSL is a c-based language. Any registered dynamic link libraries can be controlled through Venus by defining an object type.

I prefer C# and it is designed with C# in mind. All SiLA libraries are C# and compiled into a DLL and registered upon installation.

Let me know if you need further guidance on this/if a tutorial or walk through on how to get this up and running would be useful!

6 Likes

@zachary.milot,
I am sure that many users in this forum would be interested in a detailed tutorial

6 Likes

Agreed with Max - if you can give an example or explain a bit further I’d be thrilled

3 Likes

Sorry for the delayed response—things have been quite hectic at the start of the year! but here is the how to guide:

Guide to Setting Up COM Libraries in Visual Studio

There are a few ways to make COM Libraries, but I’ll guide you through the basic C# setup in Visual Studio:


Step 1: Install .NET Components

In Visual Studio, ensure you have the .NET components installed and are running .NET Framework 4.8 or above. If you’re unsure what packages are installed, follow these steps:

  1. Open Visual Studio and select Continue without code:

  1. Go to Tools → Get Tools and Features…:

  1. Ensure that .NET desktop development is installed, and install it if not:


Step 2: Create a New Project

  1. Open Visual Studio and create a new project:

  1. Select the .NET Class Library template. Ensure you select C# if you intend to use it, rather than Visual Basic:

  1. Use a framework version of 4.8 or above to access features such as threading and efficiency improvements. Choose a unique project name to avoid conflicts. For instance, instead of “PlottingLibrary,” use something like “HSLPlotLib”:

WARNING: Ensure your project name is unique, and no copies with the same name exist on your local system. Subsequent steps may overwrite anything with the same name.


Step 3: Add Example C# Code

Here’s an example of C# code that explicitly defines a GUID and ProgID. These identifiers must be unique to your system and will be used later in Venus.

using System;
using System.Runtime.InteropServices;

namespace ExampleCOMLibrary
{
    // Explicitly assign a GUID and ProgID
    [Guid("12345678-ABCD-1234-EFAB-1234567890AB")]
    [ProgId("ExampleCOMLibrary.AlphabetConverter")]
    [ComVisible(true)]
    public class AlphabetConverter
    {
        // Public method exposed via COM to return a letter's position in the alphabet
        public int GetLetterPosition(string letter)
        {
            if (string.IsNullOrEmpty(letter) || letter.Length != 1 || !char.IsLetter(letter[0]))
            {
                throw new ArgumentException("Input must be a single letter.");
            }

            char uppercaseLetter = char.ToUpper(letter[0]);
            return uppercaseLetter - 'A' + 1;
        }
    }
}

Use an online GUID generator, like https://www.guidgenerator.com to generate a unique GUID.


Step 4: Build the Solution

  1. Build the solution. By default, your .dll will be located in the bin → Debug → net48 folder of your project.

  2. If you use dependencies from NuGet, they’ll be listed here. Consider using the ILMerge and ILMerge.MSBuild.Task NuGet packages to create a single .dll with all dependencies included.


Step 5: Register the DLL

We need to register the DLL in Windows so it can be used by multiple processes.

WARNING: Ensure your GUID and ProgID are unique and no duplicates exist on your local system. This will overwrite anything with the same name.

  1. Use the Global Assembly Cache (GAC) for registration. This allows your object to be shared across processes.

  2. Run RegAsm.exe (for 32-bit applications) from the following path:

    C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe
    
  3. Register your DLL using the following command (run Command Prompt as Administrator):

    "C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /codebase "C:\Path\To\Your\DLL\PlotLibrary.dll"
    

Once registered, the code can be used immediately. If you update the .dll, you don’t need to re-register it as long as the file path remains unchanged.

To Unregister:
If needed, you can unregister the DLL using:

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /codebase /unregister "C:\Path\To\Your\DLL\PlotLibrary.dll"

Step 6: Call the COM Object from Venus

Define the COM object from the DLL in Venus. Below is an example HSL code snippet:

namespace hslAlphabet
{
    // Object in Venus to define the COM object
    object comObject;

    // Function declaration
    function convertNumberToLetter(variable xyz) variable
    {
        variable strReturn;
        // Create an instance of the COM object
        comObject.CreateObject("ExampleCOMLibrary.AlphabetConverter");

        // Call the method and store the result
        strReturn = comObject.NumberToLetter(xyz);

        return(strReturn);
    }
}

namespace _Method
{ 
    method main() void
    {
        // Initialize xyz to 3
        variable xyz (3);

        // Trace outputs the result as a string
        Trace("The value of ", xyz, " is: ", hslAlphabet::convertNumberToLetter(xyz));  
    } 
}

WARNING: Venus will use system resources for any compiled code run from COM libraries. If your program is resource-intensive, consider using an intermediary COM object or alternatives such as data piping, shared memory, or REST APIs.


Let me know if you’d like further details about intermediary COM objects. Happy building, and as always, sandbox and test before deploying!

11 Likes

This is really useful! Visual Studio is awesome

1 Like

I might do a follow-up on how to implement piping, but I’m excited to see if anyone comes up with cool libraries using this! A ton of HSL libraries already use these connectors as a way to interact with system components, and this is a way to extend the reach of Venus outside the Hamilton ecosystem.

Reminder: Make sure you’re using Visual Studio 2022 (not Visual Studio Code). Microsoft has a habit of confusing naming conventions, so double-check you’re working in the right environment.


Common Default COM Objects in Windows

Windows has plenty of built-in COM libraries you can leverage. Here are some of the most common ones:

Windows Script Host (WSH)

  • Scripting.FileSystemObject

    • ProgID: Scripting.FileSystemObject
    • Purpose: Provides access to the file system (e.g., reading/writing files, folder management).
  • WScript.Shell

    • ProgID: WScript.Shell
    • Purpose: Interact with the Windows Shell (e.g., registry, environment variables, running commands).
  • SAPI.SpVoice

    • ProgID: SAPI.SpVoice
    • Purpose: Text-to-speech functionality.

Shell COM Objects

  • Shell.Application

    • ProgID: Shell.Application
    • Purpose: Interact with the Windows Shell (e.g., launching applications, opening files/folders).
  • WindowsInstaller.Installer

    • ProgID: WindowsInstaller.Installer
    • Purpose: Manage Windows Installer packages.

Microsoft Office (if installed)

  • Excel.Application

    • ProgID: Excel.Application
    • Purpose: Automate Microsoft Excel.
  • Word.Application

    • ProgID: Word.Application
    • Purpose: Automate Microsoft Word.
  • Outlook.Application

    • ProgID: Outlook.Application
    • Purpose: Automate Microsoft Outlook.

Let me know if there’s any interest for a guide on making a GUI Windows form app/a how to on piping data to another system process.

3 Likes

Hi Zac,
impressive guide, thank you very much on behalf of all the users around here.
One disadvantage of Com libraries as far as I know is that they contradict self-contained publishing. How could this be avoided, is there an alternative? This is important, for example, if you want to develop a completely encapsulated solution
Cheers
Max

You’re welcome! It defines took me a little bit to make sure I included every step by step detail to make sure it’s easy to follow.

You bring up a fantastic point. If you notice most distributed libraries which are feature rich are not in a static copy/paste library but most rely on installers.

Inno Setup is used heavily within this library building, and is fairly simple to use and build an instruction guide to paste the files and register the com objects to the global assembly cashe.

I can absolutely post a guide on how to do this/encapsulate the solution for distribution if you think that would be helpful for the community!