Integrating AI Gateway Module with Windows .NET/C# applications
This guide will go through the process of integrating and using AI Gateway Module in your .NET/C# desktop application.
Don't forget to generate your AI Gateway Module API Key and download Library from Developers dashboard first.
Integration
On Windows, the Module service is provided for x64, x86, and arm64 architectures. The Module service dynamic-link libraries x64\bin\aigw.dll, x86\bin\aigw.dll, and arm64\bin\aigw.dll should be accessible to your application's executable. It is recommended to place them in the same directory tree as your application's executable. If you need to support only one architecture, you can use only one of the provided libraries.
You cannot mix architectures (e.g., an x64 process cannot load an arm64 DLL).
With Visual Studio
If you are using Visual Studio, you can automatically place the Module service dynamic-link libraries in the output directory using a post-build event:
- Right-click on your project in Solution Explorer and select Properties.
- In the properties window, go to Build Events on the left sidebar.
- In the Post-build event command line field add the following command:
mkdir "$(TargetDir)\x86"
mkdir "$(TargetDir)\x64"
mkdir "$(TargetDir)\arm64"
copy /Y "<path to>\x86\bin\aigw.dll" "$(TargetDir)\x86\aigw.dll"
copy /Y "<path to>\x64\bin\aigw.dll" "$(TargetDir)\x64\aigw.dll"
copy /Y "<path to>\arm64\bin\aigw.dll" "$(TargetDir)\arm64\aigw.dll" - Replace
<path to>with the path to the directory where the Module service dynamic-link libraries are located.
Module service functions can be called from managed code using Platform Invoke (P/Invoke) functionality.
In order to call the Module service functions, add the following class to your application's source code:
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
static class Aigw
{
private const string File = "aigw.dll";
static Aigw()
{
var root = AppDomain.CurrentDomain.BaseDirectory;
string arch;
if (RuntimeInformation.ProcessArchitecture == Architecture.X86)
arch = "x86";
else if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
arch = "x64";
else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64)
arch = "arm64";
else
throw new PlatformNotSupportedException("Unsupported architecture");
string path = Path.Combine(root, arch, File);
if (LoadLibrary(path) == IntPtr.Zero)
throw new DllNotFoundException($"{path} (Win32 {Marshal.GetLastWin32Error()})");
AppDomain.CurrentDomain.ProcessExit += OnExit;
AppDomain.CurrentDomain.DomainUnload += OnExit;
}
public static void Init(string api_key)
{
if (aigw_init(api_key) < 0)
throw new Exception("Failed to initialize the service");
}
public static bool Start()
{
if (aigw_start(out var consent) < 0)
throw new Exception("Failed to start the service");
return consent;
}
public static void Stop()
{
if (aigw_stop() < 0)
throw new Exception("Failed to stop the service");
}
public static string Identify()
{
UIntPtr size = UIntPtr.Zero;
if (aigw_identify(null, ref size) < 0)
throw new Exception("Failed to get size of identity data");
var data = new StringBuilder((int)size);
size = (UIntPtr)data.Capacity;
if (aigw_identify(data, ref size) < 0)
throw new Exception("Failed to get identity data");
return data.ToString();
}
public static bool IsRunning()
{
if (aigw_is_running(out var running) < 0)
throw new Exception("Failed to check if the service is running");
return running;
}
public static void OptIn()
{
if (aigw_opt_in() < 0)
throw new Exception("Failed to opt in user");
}
public static void OptOut()
{
if (aigw_opt_out() < 0)
throw new Exception("Failed to opt out user");
}
public static bool IsOptedIn()
{
if (aigw_is_opted_in(out var consent) < 0)
throw new Exception("Failed to check if user is opted in");
return consent;
}
public static bool RequestConsent()
{
if (aigw_request_consent(out var consent) < 0)
throw new Exception("Failed to request user consent");
return consent;
}
public static void Log(string dir)
{
if (aigw_log(dir) < 0)
throw new Exception("Failed to enable logging for the service");
}
public static void Mute()
{
if (aigw_mute() < 0)
throw new Exception("Failed to disable logging for the service");
}
private static void OnExit(object sender, EventArgs e)
{
try
{
Stop();
}
catch { }
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern IntPtr LoadLibrary(string file);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_init(string api_key);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_start(out bool consent);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_stop();
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_identify([MarshalAs(UnmanagedType.LPStr)] StringBuilder data, ref UIntPtr size);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_is_running(out bool running);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_opt_in();
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_opt_out();
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_is_opted_in(out bool consent);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_request_consent(out bool consent);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_log(string dir);
[DllImport(File, CallingConvention = CallingConvention.Cdecl)]
private static extern int aigw_mute();
}
Full working example can be found in the samples/dotnet directory of the downloaded AI Gateway Module.
Usage
In the above example, the class calls .Stop() when the application is closing. It is recommended to do this in your application as well so the Module service shuts down cleanly.
Note that .Start() and .Stop() are non-blocking. Internally, starting and stopping the Module service are asynchronous, so there may be a slight delay before the action takes effect.
Initializing Module service
To initialize the Module service, call .Init():
Aigw.Init("your-api-key");
The parameter is your AI Gateway Module API Key. If the service is already initialized and a different API key is provided, the old instance is terminated and a new one is initialized. If the service is already initialized and the same API key is provided, the call effectively does nothing.
It is required to call this function before any other Module service function.
Starting Module service
To start the Module service, call .Start():
bool consent = Aigw.Start();
It checks whether explicit user consent was given previously. The current consent state is returned by the method. If consent was given previously, the Module service starts. If not, the Module service does not start and the method returns false.
If the Module service is already running, the call effectively does nothing.
Stopping Module service
To stop the Module service, call .Stop():
Aigw.Stop();
Stops the Module service if it is running. If the Module service is not running, this method does nothing.
Identifying Module service
To retrieve the Module service identifier string, call .Identify():
string identifier = Aigw.Identify();
This is an immediate operation and returns an opaque string that uniquely identifies the running Module service.
Verifying Module service state
To verify whether the Module service is running, call .IsRunning():
bool running = Aigw.IsRunning();
This is an immediate operation and reports Module service state at the current time without blocking.
Providing user consent
To provide user consent, call .OptIn():
Aigw.OptIn();
Records that user consent was given and allows the Module service to start. Subsequent calls to .Start() are allowed to start the Module service.
Revoking user consent
To revoke user consent, call .OptOut():
Aigw.OptOut();
Records that user consent was revoked. The Module service stops if it is running. Subsequent calls to .Start() are not allowed to start the Module service.
Verifying user consent state
To verify whether user consent was given, call .IsOptedIn():
bool consent = Aigw.IsOptedIn();
Returns the stored consent state.
Requesting user consent
To request user consent, call .RequestConsent():
bool consent = Aigw.RequestConsent();
Displays the default user agreement window.
If the user accepts the agreement, consent is stored and subsequent calls to .Start() are allowed to start the Module service.
If the user declines or closes the window, subsequent calls to .Start() are not allowed unless consent was previously given.
This function is blocking and returns only after the user accepts or declines.
Enable logging
To enable logging, call .Log():
Aigw.Log("C:\\path\\to\\log\\directory");
Enables logging for the Module service. Log files are created in the specified directory. If the directory is not specified, log files will be created in the current working directory of your application. Logs are also written to standard output.
Disable logging
To disable logging, call .Mute():
Aigw.Mute();
Disables logging for the Module service. Any log file is closed and writing to standard output is stopped.
Function reference
aigw_start() and aigw_stop() are non-blocking. Internally, starting and stopping the AI Gateway Module service are asynchronous operations, so there can be a slight delay before the action takes effect.
aigw_init
Initialize the Module service.
int32_t aigw_init(const char *api_key);
Parameters
| Name | Type | Description |
|---|---|---|
api_key | const char* | Your API key provided by AI Gateway Module. |
Returns
0 on success; otherwise a negative error code.
Remarks
- If the service is already initialized and a different API key is provided, the old instance is terminated and a new one is initialized.
- If the service is already initialized and the same API key is provided, the function call effectively does nothing.
api_keyis copied by the Module; its memory does not need to remain valid after the call returns.
It is required to call this function before any other Module service function.
aigw_start
Start the Module service.
int32_t aigw_start(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: consent state. Set to 1 if user consent was previously given, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Checks whether explicit user consent was given before. The current consent state is returned via
*state. - If consent was previously given, the Module service starts. If not, the service does not start and
*stateis set to0. - If the service is already running, the function call effectively does nothing.
It is recommended to obtain user consent before starting the Module service.
aigw_stop
Stop the Module service.
int32_t aigw_stop(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Stops the Module service if it is running.
- If the service is not running, this function does nothing.
It is recommended to stop the Module service before closing your application so the service shuts down cleanly.
aigw_identify
Get the Module service identifier.
int32_t aigw_identify(char *data, size_t *size);
Parameters
| Name | Type | Description |
|---|---|---|
data | char* | Buffer to receive a NUL-terminated ASCII string. If not NULL, the function writes up to *size bytes and sets *size to the number of bytes actually written. |
size | size_t* | In/out. If data is NULL, on return *size is set to the number of bytes required to store the full NUL-terminated string. If data is not NULL, on return *size is set to the number of bytes actually written. |
Returns
0 on success; otherwise a negative error code.
Remarks
- The identifier is stable across runs on the device.
- Use the two-call pattern to retrieve the full value: call with
data == NULLto get required size (in bytes), allocate that many bytes, then call again withdataandsize. - The returned string is NUL-terminated and plain ASCII.
- If the provided buffer (
data/*size) is smaller than required, the string is truncated to fit (ensuring NUL termination when*size > 0),*sizeis set to the number of bytes actually written, and the function returns0.
aigw_is_running
Check if the Module service is running.
int32_t aigw_is_running(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if the service is running, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
aigw_opt_in
Provide user consent.
int32_t aigw_opt_in(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Persists that user consent was given and informs the Module service that it may start.
- Subsequent calls to
aigw_start()will be allowed to start the service.
aigw_opt_out
Revoke user consent.
int32_t aigw_opt_out(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Persists that user consent was revoked and informs the Module service that it should stop if running.
- Subsequent calls to
aigw_start()will not be allowed to start the service.
aigw_is_opted_in
Check whether user consent was given.
int32_t aigw_is_opted_in(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if consent was given, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Returns the stored consent state via
*state.
aigw_request_consent
Display the default user agreement window and capture consent.
int32_t aigw_request_consent(int32_t *state);
Parameters
| Name | Type | Description |
|---|---|---|
state | int32_t* | Out: set to 1 if the user accepts, otherwise 0. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Shows the default user agreement UI.
- If the user accepts, consent is stored and the Module service may start. Subsequent
aigw_start()calls are allowed. - If the user declines or closes the window, subsequent
aigw_start()calls are not allowed unless consent was previously given.
This function is blocking and returns only after the user accepts or declines the agreement.
aigw_log
Enable logging for the Module service.
int32_t aigw_log(const char *dir);
Parameters
| Name | Type | Description |
|---|---|---|
dir | const char* | Directory where log files will be stored. If NULL or empty, logs are created in the current working directory. |
Returns
0 on success; otherwise a negative error code.
Remarks
- Enables logging and writes logs to the specified directory (created if it does not exist).
- Logs are also written to standard output.
- Subsequent calls to
aigw_log()create a new log file in the specified directory.
aigw_mute
Disable logging for the Module service.
int32_t aigw_mute(void);
Returns
0 on success; otherwise a negative error code.
Remarks
- Disables logging: closes any open log file and stops writing to standard output.
- Existing log files are not deleted and can be inspected for debugging.