Accessing C++ standard library in HSL?

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!

15 Likes