https://github.com/3f/dllexport
.NET DllExport with .NET Core support (aka 3F/DllExport aka DllExport.bat)
https://github.com/3f/dllexport
conari coreclr coreclr-ilasm dllexport dotnet-dllexport exported-functions getnutool hmsbuild ilasm ildasm mvssln pe32 pe32-plus pinvoke tools
Last synced: 12 days ago
JSON representation
.NET DllExport with .NET Core support (aka 3F/DllExport aka DllExport.bat)
- Host: GitHub
- URL: https://github.com/3f/dllexport
- Owner: 3F
- License: mit
- Created: 2016-06-24T10:42:26.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2025-02-26T22:49:12.000Z (about 2 months ago)
- Last Synced: 2025-04-11T00:41:38.438Z (12 days ago)
- Topics: conari, coreclr, coreclr-ilasm, dllexport, dotnet-dllexport, exported-functions, getnutool, hmsbuild, ilasm, ildasm, mvssln, pe32, pe32-plus, pinvoke, tools
- Language: C#
- Homepage:
- Size: 3.04 MB
- Stars: 1,005
- Watchers: 55
- Forks: 134
- Open Issues: 18
-
Metadata Files:
- Readme: Readme.md
- Changelog: changelog.txt
- Funding: .github/FUNDING.yml
- License: LICENSE.txt
- Authors: AUTHORS.txt
Awesome Lists containing this project
README
# [.NET DllExport](https://github.com/3F/DllExport)
*.NET DllExport* with .NET Core support (aka ***3F**/DllExport* aka *DllExport.**bat***)
[](https://ci.appveyor.com/project/3Fs/dllexport-ix27o/branch/master)
[](https://github.com/3F/DllExport/releases/latest)
[](https://github.com/3F/DllExport/blob/master/LICENSE.txt)[`DllExport`](https://3F.github.io/DllExport/releases/latest/manager/)`-help`
```csharp
[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](https://sites.google.com/site/robertgiesecke/Home/uploads/unmanagedexports).
***.NET DllExport*** is a [different project](https://github.com/3F/DllExport/issues/87#issuecomment-438576100) that was developed by Denis Kuzmin [ 「 ☕ 」 ](https://3F.github.io/fund)
```
Copyright (c) 2009-2015 Robert Giesecke
Copyright (c) 2016-2025 Denis Kuzmin github/3F
```> [ ***[Quick start](https://github.com/3F/DllExport/wiki/Quick-start)*** ] [ [Examples: C++, C#, Java, ...](https://github.com/3F/DllExport/wiki/Examples) ]
> -> { **[Wiki](https://github.com/3F/DllExport/wiki)** } { [🧪 Demo src](https://github.com/3F/Examples/tree/master/DllExport/BasicExport) }[](https://3F.github.io/DllExport/releases/latest/manager/)
[](https://www.youtube.com/watch?v=QXMj9-8XJnY)For Lua, consider using [LuNari](https://github.com/3F/LuNari)
```csharp
[DllExport]
public static int entrypoint(IntPtr L)
{
using Lua lua = new("Lua.dll");
...
lua.pushcclosure(L, onProc, 0);
lua.setglobal(L, "onKeyDown");
LuaNumber num = lua.tonumber(L, 7);
...
}
```For working with **unmanaged** memory including native or binary data from the heap and binding between .NET and unmanaged native C/C++ etc, try [Conari](https://github.com/3F/Conari) (Wiki. [**Quick-start**](https://github.com/3F/Conari/wiki/Quick-start))
[`[⏯]`](https://github.com/3F/DllExport/blob/master/src/DllExport/assets/NetfxAsset/Basic.cs)
```csharp
[DllExport] // DllExportModifiedClassLibrary.dll
public static IntPtr callme(TCharPtr str, IntPtr structure)
{
if(str != "Hello world!") return IntPtr.Zero;structure.Native().f("x", "y").build(out dynamic v);
if(v.x > v.y)
{
structure.Access().write(8);
}
return new NativeArray(-1, v.x, 1, v.y);
}
```[`[⏯]`](https://github.com/3F/DllExport/blob/master/src/DllExport/UnitedTest/NetfxAssetBasicTest.cs)
```csharp
... // host side via C/C++, Java, Rust, Python, ... or even same dotnet C#
using NativeString ns = new("Hello world!");
using NativeStruct nstruct = new(new Arg() { x = 7, y = 5 });using dynamic l = new ConariX("DllExportModifiedClassLibrary.dll");
IntPtr ptr = l.callme(ns, nstruct);using NativeArray nr = new(4, ptr); // (nstruct.Data.x == 8) != (nr[1] == 7)
```*.NET DllExport* supports both Library (**.dll**) and Executable (**.exe**) PE modules.
`[⏯]` See also demo project here: https://github.com/3F/Examples/tree/master/DllExport/BasicExport
## How does it work
Current features has been implemented through [ILDasm](https://github.com/3F/coreclr/tree/master/src/ildasm) & [ILAsm](https://github.com/3F/coreclr/tree/master/src/ilasm) that prepares all the necessary steps via `.export` directive ([it's part of the ILAsm compiler, **not** CLR](https://github.com/3F/DllExport/issues/45#issuecomment-317802099)).
**What inside ? how does work the .export directive ?**
Read about format PE32/PE32+, start with grammar from asmparse and move to writer:
```cpp
...
//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](https://github.com/3F/DllExport/issues/125#issuecomment-561245575) / [about mscoree](https://github.com/3F/DllExport/issues/45#issuecomment-317802099) / [DllMain & the export-table](https://github.com/3F/DllExport/issues/5#issuecomment-240697109) / [DllExport.dll](https://github.com/3F/DllExport/issues/28#issuecomment-281957212) / [ordinals](https://github.com/3F/DllExport/issues/8#issuecomment-245228065) ...
## How to get DllExport
Use directly latest stable [DllExport.bat](https://3F.github.io/DllExport/releases/latest/manager/) (~28 KB). Read [Wiki](https://github.com/3F/DllExport/wiki/Quick-start)
Note: NuGet features are not guaranteed [[?](https://github.com/3F/DllExport/wiki/DllExport-Manager-Q-A)] (tl;dr something may not work or not work properly)
* Get it from [GitHub Releases](https://github.com/3F/DllExport/releases/latest). Or link to latest stable: https://3F.github.io/DllExport/releases/latest/manager/
* Or from [](https://www.nuget.org/packages/DllExport/) 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*](https://github.com/3F/GetNuTool)Read [ **[Documentation](https://github.com/3F/DllExport/wiki/DllExport-Manager)** ]
## Build .NET DllExport from source
```bat
git clone https://github.com/3F/DllExport.git DllExport
cd DllExport
```Call *build.bat* to build final binaries like `DllExport..nupkg`, Manager, tests, zip-archives, and related:
```batch
.\build Release
```Note, this relies on [vsSolutionBuildEvent](https://github.com/3F/vsSolutionBuildEvent) scripting **if** you're using Visual Studio **IDE**.
### Modified IL Assembler
We're using **[3F's](https://github.com/3F) modified versions** specially for *.NET DllExport* project
* https://github.com/3F/coreclrThis helps to avoid some problems [like this](https://github.com/3F/DllExport/issues/125#issuecomment-561245575), or [this](https://github.com/3F/DllExport/issues/17), and more ...
To build minimal version:
```batch
.\build # ilasm -x64
```Make sure you have installed [CMake](https://cmake.org/download/) before build.
To build assembler and use exactly this compiled version with *DllExport*, command like:
```batch
.\build # ilasm -x64 & .\build Release
```Alternatively you can get official compiled versions via [](https://www.nuget.org/packages/ILAsm/)
Or like:
```batch
:: ILAsm/9.3.0
.tools\gnt ILAsm & .\build Release
```