Dalamud automatically initializes the library, so you can start using it immediately:
YourPlugin.cs
using FFXIVClientStructs.FFXIV.Client.System.Framework;public class YourPlugin : IDalamudPlugin { public void Initialize() { unsafe { var framework = Framework.Instance(); // Framework is already initialized! } }}
No signature resolution initialization needed - Dalamud handles this for you!
If you’re using FFXIVClientStructs outside of Dalamud or with a local copy, you need to manually initialize signature resolution.
1
Configure your project file
Update your .csproj file with the required properties:
YourProject.csproj
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net10.0</TargetFramework> <LangVersion>preview</LangVersion> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling> </PropertyGroup> <ItemGroup> <!-- Add your reference to FFXIVClientStructs here --> </ItemGroup></Project>
DisableRuntimeMarshalling is required - all types must be blittable for direct memory mapping
2
Initialize signature resolution
Before using any FFXIVClientStructs types, initialize the resolver once at startup:
Program.cs
using FFXIVClientStructs.Interop.Generated;using InteropGenerator.Runtime;unsafe { // Initialize the resolver Resolver.GetInstance.Setup(); Addresses.Register(); Resolver.GetInstance.Resolve();}
This initialization resolves all function signatures and static addresses at runtime
3
Optional: Configure caching
For faster startup times on subsequent runs, use signature caching:
Advanced Setup
using FFXIVClientStructs.Interop.Generated;using InteropGenerator.Runtime;using System.IO;unsafe { // Setup with signature cache var cacheFile = new FileInfo("signature_cache.json"); var gameVersion = "6.58"; // Current game version Resolver.GetInstance.Setup( searchBase: null, // Use default searchKey: gameVersion, // Version key for cache cacheFile: cacheFile // Cache file location ); Addresses.Register(); Resolver.GetInstance.Resolve();}
The cache file stores resolved addresses per game version, making subsequent launches nearly instant.
4
Advanced: Use Dalamud's module copy
If you’re using a local copy within a Dalamud plugin, you can scan Dalamud’s unmodified copy of the game binary:
Plugin with Local Copy
using Dalamud.Plugin.Services;using FFXIVClientStructs.Interop.Generated;using InteropGenerator.Runtime;public class YourPlugin : IDalamudPlugin { public YourPlugin(ISigScanner sigScanner) { unsafe { // Use Dalamud's pristine module copy var searchBase = (void*)sigScanner.SearchBase; Resolver.GetInstance.Setup(searchBase); Addresses.Register(); Resolver.GetInstance.Resolve(); } }}
This avoids scanning a binary that may have been modified by active hooks from other plugins
<PropertyGroup> <!-- Target .NET 10.0 for latest C# features --> <TargetFramework>net10.0</TargetFramework> <!-- Preview language features for function pointers and generators --> <LangVersion>preview</LangVersion> <!-- Required for pointer operations --> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <!-- CRITICAL: Disables automatic marshalling for direct memory mapping --> <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling> <!-- Recommended for cleaner code --> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable></PropertyGroup>
Pointer to a copy of the FFXIV module in memory. If null, scans the active game process. Use Dalamud’s SigScanner.SearchBase to scan an unmodified copy.
using FFXIVClientStructs.FFXIV.Client.System.Framework;using System;unsafe { var framework = Framework.Instance(); if (framework != null) { Console.WriteLine($"Framework found at: {(nint)framework:X}"); Console.WriteLine($"Frame counter: {framework->FrameCounter}"); Console.WriteLine("FFXIVClientStructs is working!"); } else { Console.WriteLine("ERROR: Framework instance is null"); Console.WriteLine("Check that you're running this while FFXIV is active"); }}
The game must be running for signature resolution to work. All signatures scan the active FFXIV process memory.
This usually means signature resolution failed. Check that:
You called Setup(), Register(), and Resolve() in order
The game is running when you initialize
Your game version matches the library version
Cannot use pointer types
Ensure <AllowUnsafeBlocks>true</AllowUnsafeBlocks> is set in your project file and you’re using unsafe blocks or methods.
Type marshalling errors
Add <DisableRuntimeMarshalling>true</DisableRuntimeMarshalling> to your project file. All FFXIVClientStructs types are unmanaged and cannot use automatic marshalling.
Signature resolution is slow
Use the signature cache feature with a FileInfo parameter in Setup(). The first run will be slow, but subsequent runs with the same game version will be nearly instant.