Skip to content

Getting Started

Peter Nilsson edited this page Nov 4, 2023 · 2 revisions

This guide will walk you through getting up and running with Coral. We'll cover initializing the .NET Runtime, loading your .NET assembly, creating instances of types, setting and getting field values, invoking C# methods as well as using the Internal Call feature to invoke native functions from C#.

For instructions on building Coral from source please read "Building Coral" before continuing this guide.

Initializing the .NET Runtime

To start off we have to include the HostInstance.hpp header from Coral. You will have to add Coral/Include/ to your build systems include paths, after that you should be able to include the header like this: #include <Coral/HostInstance.hpp>

In order to properly initialize the .NET Runtime you have to know the location of two files:

  1. Coral.Managed.dll
  2. Coral.Managed.runtimeconfig.json

These files should be in the output folder after you've built Coral (usually "Build/Debug/" or "Build/Release/", it doesn't matter which one you pick). Once you've found these files you might want to copy them into a folder where they're more easily accessible.

After that's done we'll initialize the .NET Runtime with this code:

Coral::HostSettings hostSettings =
{
    .CoralDirectory = "path/to/Coral.Managed.dll",
};

Coral::HostInstance coralInstance;
if (!coralInstance.Initialize(hostSettings))
{
    // Handle the case where the initialization failed
}

You can also set the message callback and the C# exception callback in the HostSettings struct if you want to handle any errors from Coral or your own C# code in native code.

The message callback is a function that Coral will call anytime something goes wrong internally, this can be useful for finding out more information about any issues you might encounter with Coral at runtime.

The exception callback is called anytime a C# exception was thrown, this might happen because of a bug in Coral, or because an exception was thrown in your own code.

You are not required to specify either of these functions, although I highly recommend that you do, since it'll help you debug any issues you might encounter.

We can set these functions like this:

void CoralMessageCallback(Coral::NativeString message, Coral::MessageLevel level)
{
}

void ExceptionCallback(std::string message)
{
}

// ...

hostSettings.MessageCallback = CoralMessageCallback;
hostSettings.ExceptionCallback = ExceptionCallback;

We'd of course want to shutdown the .NET Runtime once we're done with it, this is easily achieved by simply calling coralInstance.Shutdown();

Loading Assemblies

Assembly loading in .NET Core is done through Assembly Load Contexts, with Coral I decided to mimic this in C++ code, meaning we load assemblies into an Assembly Load Context (or ALC). For unloading we are required to unload the entire ALC, meaning we might be potentially unloading multiple assemblies all in one go.

To create an ALC and load assemblies into it we have this code:

auto alc = coralInstance.CreateAssemblyLoadContext("MyALC");
auto& assembly = alc.LoadAssembly("my/path/to/my/assembly.dll");

// Unloading
coralInstance.UnloadAssemblyLoadContext(alc);

When we create our ALC we are required to give it a name, this is just for debugging purposes, the name can be anything you like.

Clone this wiki locally