DllExport
.NET DllExport with .NET Core support (aka 3F/DllExport aka DllExport.bat)
Install / Use
/learn @3F/DllExportREADME
.NET DllExport
.NET DllExport with .NET Core support (aka 3F/DllExport aka DllExport.bat)
[DllExport("Init", CallingConvention.Cdecl)]
[DllExport(CallingConvention.StdCall)]
// Cdecl is the default calling convention in .NET DllExport
[DllExport("MyFunc")]
[DllExport]
Based on UnmanagedExports that was created by Robert Giesecke. His page.
.NET DllExport is a different project that was developed by Denis Kuzmin 「 ☕ 」
Copyright (c) 2009-2015 Robert Giesecke
Copyright (c) 2016-2025 Denis Kuzmin <x-3F@outlook.com> github/3F
[ Quick start ] [ Examples: C++, C#, Java, ... ] -> { Wiki } { 🧪 Demo }
Example of using DllExport + Conari:
[DllExport] // DllExportModifiedClassLibrary.dll
public static IntPtr callme(TCharPtr str, IntPtr structure)
{
if(str != "Hello world!") return IntPtr.Zero;
structure.Native().f<int>("x", "y").build(out dynamic v);
if(v.x > v.y)
{
structure.Access().write<int>(8);
}
return new NativeArray<int>(-1, v.x, 1, v.y);
}
... // host side via C/C++, Java, Rust, Python, ... or even same dotnet C#
using NativeString<TCharPtr> ns = new("Hello world!");
using NativeStruct<Arg> nstruct = new(new Arg() { x = 7, y = 5 });
using dynamic l = new ConariX("DllExportModifiedClassLibrary.dll");
IntPtr ptr = l.callme<IntPtr>(ns, nstruct);
using NativeArray<int> nr = new(4, ptr); // (nstruct.Data.x == 8) != (nr[1] == 7)
For Lua, consider using LuNari
[DllExport]
public static int entrypoint(IntPtr L)
{
using Lua<ILua53> lua = new("Lua.dll");
...
lua.pushcclosure(L, onProc, 0);
lua.setglobal(L, "onKeyDown");
LuaNumber num = lua.tonumber<LuaNumber>(L, 7);
...
}
.NET DllExport supports both Library (.dll) and Executable (.exe) PE modules.
How does it work
Current features has been implemented through ILDasm & ILAsm that prepares all the necessary steps via .export directive (it's part of the ILAsm compiler, not CLR).
What inside ? how does work the .export directive ?
Read about format PE32/PE32+, start with grammar from asmparse and move to writer:
...
//yacc
if(PASM->m_pCurMethod->m_dwExportOrdinal == 0xFFFFFFFF)
{
PASM->m_pCurMethod->m_dwExportOrdinal = $3;
PASM->m_pCurMethod->m_szExportAlias = $6;
if(PASM->m_pCurMethod->m_wVTEntry == 0) PASM->m_pCurMethod->m_wVTEntry = 1;
if(PASM->m_pCurMethod->m_wVTSlot == 0) PASM->m_pCurMethod->m_wVTSlot = $3 + 0x8000;
}
...
EATEntry* pEATE = new EATEntry;
pEATE->dwOrdinal = pMD->m_dwExportOrdinal;
pEATE->szAlias = pMD->m_szExportAlias ? pMD->m_szExportAlias : pMD->m_szName;
pEATE->dwStubRVA = EmitExportStub(pGlobalLabel->m_GlobalOffset+dwDelta);
m_EATList.PUSH(pEATE);
...
// logic of definition of records into EXPORT_DIRECTORY (see details from PE format)
HRESULT Assembler::CreateExportDirectory()
{
...
IMAGE_EXPORT_DIRECTORY exportDirIDD;
DWORD exportDirDataSize;
BYTE *exportDirData;
EATEntry *pEATE;
unsigned i, L, ordBase = 0xFFFFFFFF, Ldllname;
...
~ now we're ready to miracles ~ vtfxup thunk stubs and ~...
Read also my brief explanations here: AssemblyRef encoding / about mscoree / DllMain & the export-table / DllExport.dll / ordinals ...
How to get DllExport
Does DllExport support NuGet ?
Most likely yes. But NuGet features are not guaranteed (tl;dr something may not work or not work properly)
Use directly latest stable DllExport.bat (~28 KB). Read Wiki
- Get it from GitHub Releases. Or link to latest stable: https://3F.github.io/DllExport/releases/latest/manager/
- Or from
Visual Studio Package Manager can still distribute and activate DllExport.bat for solution folder in most default setup cases.
- Or use embeddable package manager GetNuTool
Read [ Documentation ]
Build .NET DllExport from source
git clone https://github.com/3F/DllExport.git DllExport
cd DllExport
Call build.bat to build final binaries like DllExport.<version>.nupkg, Manager, tests, zip-archives, and related:
.\build Release
Note, this relies on vsSolutionBuildEvent scripting if you're using Visual Studio IDE.
Modified IL Assembler
We're using 3F's modified versions specially for .NET DllExport project
- https://github.com/3F/coreclr
This helps to avoid some problems like this, or this, and more ...
To build minimal version:
.\build # ilasm -x64
Make sure you have installed CMake before build.
To build assembler and use exactly this compiled version with DllExport, command like:
.\build # ilasm -x64 & .\build Release
Alternatively you can get official compiled versions via
Or like:
.tools\gnt ILAsm & .\build Release


