This module is designed to be a drop-in replacement for dynlib pragma and dynlib module in Windows. The main part of this module is a pure nim implementation of the famous MemoryModule library. So that the we can embed all DLLs into the main EXE file.
Types
MemoryModule = ptr MemoryModuleObj
- Pointer to a MemoryModule object.
DllContent = distinct string
- Represents DLL file in binary format.
Procs
proc checkedLoadLib(data: DllContent): MemoryModule {...}{.inline, raises: [Exception, LibraryError], tags: [RootEffect].}
- Loads a DLL from memory. Raise LibraryError if the DLL could not be loaded.
proc checkedLoadLib(data: openArray[byte | char]): MemoryModule {...}{.inline.}
- Loads a DLL from memory. Raise LibraryError if the DLL could not be loaded.
proc checkedSymAddr(lib: MemoryModule; name: string | LPCSTR): pointer {...}{.inline.}
- Retrieves the address of a procedure from DLL by name. Raise LibraryError if the symbol could not be found.
proc checkedSymAddr(lib: MemoryModule; ordinal: range[0 .. 65535]): pointer {...}{.inline, raises: [LibraryError], tags: [].}
- Retrieves the address of a procedure from DLL by ordinal. Raise LibraryError if the ordinal out of range.
proc loadLib(data: DllContent): MemoryModule {...}{.inline, raises: [], tags: [RootEffect].}
- Loads a DLL from memory. Returns nil if the DLL could not be loaded.
proc loadLib(data: openArray[byte | char]): MemoryModule {...}{.inline.}
- Loads a DLL from memory. Returns nil if the DLL could not be loaded.
proc symAddr(lib: MemoryModule; name: string | LPCSTR): pointer {...}{.inline.}
- Retrieves the address of a procedure from DLL by name. Returns nil if the symbol could not be found.
proc symAddr(lib: MemoryModule; ordinal: range[0 .. 65535]): pointer {...}{.inline, raises: [], tags: [].}
- Retrieves the address of a procedure from DLL by ordinal. Returns nil if the ordinal out of range.
proc unloadLib(lib: MemoryModule) {...}{.inline, raises: [Exception], tags: [RootEffect].}
- Unloads the DLL.
proc run(lib: MemoryModule): int {...}{.discardable, raises: [LibraryError, Exception], tags: [RootEffect].}
-
Execute entry point (EXE only). The entry point can only be executed if the EXE has been loaded to the correct base address or it could be relocated (i.e. relocation information have not been stripped by the linker).
Important: calling this function will not return, i.e. once the loaded EXE finished running, the process will terminate.
Raise LibraryError if the entry point could not be executed.
proc findResource(lib: HMODULE; name: LPCTSTR; typ: LPCTSTR; lang: WORD = 0): HRSRC {...}{. raises: [LibraryError], tags: [].}
- Find the location of a resource with the specified type, name and language.
proc sizeOfResource(lib: HMODULE; resource: HRSRC): DWORD {...}{.raises: [], tags: [].}
- Get the size of the resource in bytes.
proc loadResource(lib: HMODULE; resource: HRSRC): HGLOBAL {...}{.raises: [], tags: [].}
- Get a pointer to the contents of the resource.
proc loadString(lib: HMODULE; id: UINT; lang: WORD = 0): string {...}{.raises: [LibraryError], tags: [].}
- Load a string resource.
proc findResource(lib: MemoryModule; name: LPCTSTR; typ: LPCTSTR; lang: WORD = 0): HRSRC {...}{. inline, raises: [LibraryError], tags: [].}
- Find the location of a resource with the specified type, name and language.
proc sizeOfResource(lib: MemoryModule; resource: HRSRC): DWORD {...}{.inline, raises: [LibraryError], tags: [].}
- Get the size of the resource in bytes.
proc loadResource(lib: MemoryModule; resource: HRSRC): HGLOBAL {...}{.inline, raises: [LibraryError], tags: [].}
- Get a pointer to the contents of the resource.
proc loadString(lib: MemoryModule; id: UINT; lang: WORD = 0): string {...}{.inline, raises: [LibraryError], tags: [].}
- Load a string resource.
proc unhook(lib: MemoryModule) {...}{.raises: [], tags: [].}
- Removes the hooks.
proc hook(lib: MemoryModule; name: string) {...}{.raises: [], tags: [].}
- Hooks the system API (LoadLibrary and GetProcAddress only) with specified name. Following requests will be redirected to the memory module
proc checkedMemlookup(callPtr: ptr pointer; dll: DllContent; sym: LPCSTR) {...}{. raises: [Exception, LibraryError], tags: [RootEffect].}
- A helper used by memlib macro.
proc memlookup(callPtr: ptr pointer; dll: DllContent; sym: LPCSTR) {...}{.raises: [], tags: [RootEffect].}
- A helper used by memlib macro.
proc checkedLibLookup(callPtr: ptr pointer; lib: MemoryModule; sym: LPCSTR) {...}{. raises: [LibraryError], tags: [].}
- A helper used by memlib macro.
proc libLookup(callPtr: ptr pointer; lib: MemoryModule; sym: LPCSTR) {...}{.raises: [], tags: [].}
- A helper used by memlib macro.
proc checkedRtlookup(callPtr: ptr pointer; name: string; sym: LPCSTR) {...}{. raises: [LibraryError], tags: [].}
- A helper used by memlib macro.
proc rtlookup(callPtr: ptr pointer; name: string; sym: LPCSTR) {...}{.raises: [], tags: [].}
- A helper used by memlib macro.
proc staticReadDllWithName(dll: string; hint = true): (string, DllContent) {...}{. compiletime, raises: [ValueError, LibraryError], tags: [ReadEnvEffect, ReadDirEffect].}
- Compile-time find and read library proc for DLL embedding. Returns the path and the binary in DllContent format. Supports dynlib name patterns. For example: libtcl(|8.5|8.4).
proc staticReadDll(dll: string; hint = true): DllContent {...}{.compiletime, raises: [ValueError, LibraryError], tags: [ReadEnvEffect, ReadDirEffect].}
- Compile-time find and read library proc for DLL embedding. Returns the binary in DllContent format. Supports dynlib name patterns. For example: libtcl(|8.5|8.4).
Macros
macro checkedMemlib(dll, def: untyped): untyped
- dynlib pragma replacement to load DLL from memory or at runtime. Raise LibraryError if error occurred. See memlib for details.
macro memlib(dll, def: untyped): untyped
-
dynlib pragma replacement to load DLL from memory or at runtime. Accepts a MemoryModule, DllContent, or string. The program will crash if error occurred, so only use this for trusted DLL.
Parameter Meaning MemoryModule Uses the DLL loaded by loadLib or checkedLoadLib. DllContent Loads DLL in binary format that returned by staticReadDll. string Loads the DLL at runtime by system API. Examples:
const dll = staticReadDll("sqlite3_64.dll") let lib = loadLib(dll) proc libversion(): cstring {...}{.cdecl, memlib: lib, importc: "sqlite3_libversion".} echo libversion()
Examples:
const dll = staticReadDll("sqlite3_64.dll") proc libversion(): cstring {...}{.cdecl, memlib: dll, importc: "sqlite3_libversion".} echo libversion()
Examples:
proc libversion(): cstring {...}{.cdecl, memlib: "sqlite3_64.dll", importc: "sqlite3_libversion".} echo libversion()
macro withPragma(pragma, body: untyped): untyped
-
push pragma replacement.
Examples:
proc test() = const dll = staticReadDll("sqlite3_64.dll") withPragma {cdecl, memlib: dll, importc: "sqlite3_libversion"}: proc libversion(): cstring echo libversion()
macro buildPragma(pragma, body: untyped): untyped
-
pragma pragma replacement.
Examples:
proc test() = const dll = staticReadDll("sqlite3_64.dll") buildPragma {cdecl, memlib: dll, importc: "sqlite3_libversion"}: mylib proc libversion(): cstring {...}{.mylib.} echo libversion()