.NET DllExport with .NET Core support (a.k.a. 3F/DllExport a.k.a. DllExport.bat)
DllExport
-action Configure
[?]
[DllExport("Init", CallingConvention.Cdecl)]
// __cdecl is the default calling convention
[DllExport(CallingConvention.StdCall)]
[DllExport("MyFunc")]
[DllExport]
Based on UnmanagedExports that was created by Robert Giesecke. His page.
.NET DllExport is a different unrelated project that was developed by Denis Kuzmin 「 ❤ 」
Copyright (c) 2009-2015 Robert Giesecke
Copyright (c) 2016-2024 Denis Kuzmin <x-3F@outlook.com> github/3F
[ Quick start ] [ Examples: C++, C#, Java, ... ] -> { Wiki } { 🧪 Demo src }
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);
...
}
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 (Wiki. Quick-start)
[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)
.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
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 ~
Read also my brief explanations here: AssemblyRef encoding / about mscoree / DllMain & the export-table / DllExport.dll / ordinals ...
Put this inside solution folder, then click it there
Since 1.6+ does not provide official support for NuGet [?], something somewhere may not work or not work properly.
In any case you need DllExport.bat (~20 KB) inside your solution folder. Read Wiki. Quick-start
You can get it from any trusted places:
- GitHub Releases. Alias to latest stable manager: https://3F.github.io/DllExport/releases/latest/manager/
- Visual Studio Package Manager can still distribute and activate DllExport.bat for solution folder in most default setup cases.
- You can also use embeddable package manager GetNuTool to reach a remote DllExport.bat or .nupkg package.
Read [ Documentation ]
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.
We're using 3F's modified versions specially for .NET DllExport project
This helps to avoid some problems like this, or this, and more ...
To build minimal version (it will not include all components as for original coreclr repo):
Restore git submodule or use repo: https://github.com/3F/coreclr.git
git submodule update --init --recursive
Make sure that you have installed CMake, then:
build-s -all -x86 -x64 Release