From 2b95a7ec769eccb9e1913416417c1caf613e0bca Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Tue, 15 Feb 2022 02:00:47 +0900 Subject: [PATCH 01/10] Update copyright information --- Joveler.DynLoader/Joveler.DynLoader.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Joveler.DynLoader/Joveler.DynLoader.csproj b/Joveler.DynLoader/Joveler.DynLoader.csproj index 745366c..582fb4d 100644 --- a/Joveler.DynLoader/Joveler.DynLoader.csproj +++ b/Joveler.DynLoader/Joveler.DynLoader.csproj @@ -10,7 +10,7 @@ Cross-platform native dynamic library loader for .NET. Provides advanced P/Invoke functionality using NativeLibrary, LoadLibrary and libdl. Supports Windows, Linux, and macOS. - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2022 Hajin Jang MIT https://github.com/ied206/Joveler.DynLoader images\Logo.png From 2a8942474ab17f9f5a50af60d476b78a33e63a2f Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Fri, 30 Dec 2022 03:02:11 +0900 Subject: [PATCH 02/10] Use .NET FX 4.8.1 on tests, deprecate 4.5.2 target --- .../Joveler.DynLoader.Tests.csproj | 22 +++++----- .../SampleScript.netfx.targets | 42 +++++++++++++++---- Joveler.DynLoader/Joveler.DynLoader.csproj | 4 +- 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj b/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj index 38fb8b5..fd418d0 100644 --- a/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj +++ b/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj @@ -1,10 +1,8 @@  - - net48;net6.0 - - net6.0 + + net481;net6.0 net6.0 @@ -19,13 +17,13 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + @@ -48,8 +46,8 @@ - - + + x86\%(FileName)%(Extension) PreserveNewest @@ -58,6 +56,10 @@ x64\%(FileName)%(Extension) PreserveNewest + + arm64\%(FileName)%(Extension) + PreserveNewest + diff --git a/Joveler.DynLoader.Tests/SampleScript.netfx.targets b/Joveler.DynLoader.Tests/SampleScript.netfx.targets index ef21b43..1928ca3 100644 --- a/Joveler.DynLoader.Tests/SampleScript.netfx.targets +++ b/Joveler.DynLoader.Tests/SampleScript.netfx.targets @@ -33,6 +33,7 @@ HasTrailingSlash('$(MSBuildThisFileDirectory)')"> + + arm64\%(FileName)%(Extension) + PreserveNewest + @@ -89,6 +94,16 @@ + + + + + + + + + bin\arm64\%(Filename)%(Extension) + + + @@ -166,18 +196,21 @@ $(PostBuildEventDependsOn); CopyInteropLibFiles_x86; CopyInteropLibFiles_x64; + CopyInteropLibFiles_arm4; CopyInteropMgcFiles; $(BuildDependsOn); CopyInteropLibFiles_x86; CopyInteropLibFiles_x64; + CopyInteropLibFiles_arm64; CopyInteropMgcFiles; $(CleanDependsOn); CleanInteropLibFiles_x86; CleanInteropLibFiles_x64; + CleanInteropLibFiles_arm64; CleanInteropMgcFiles; @@ -188,16 +221,11 @@ ****************************************************************************** --> - + CollectInteropLibFiles_x86; CollectInteropLibFiles_x64; + CollectInteropLibFiles_arm64; CollectInteropMgcFiles; $(PipelineCollectFilesPhaseDependsOn); diff --git a/Joveler.DynLoader/Joveler.DynLoader.csproj b/Joveler.DynLoader/Joveler.DynLoader.csproj index 582fb4d..965f371 100644 --- a/Joveler.DynLoader/Joveler.DynLoader.csproj +++ b/Joveler.DynLoader/Joveler.DynLoader.csproj @@ -1,6 +1,6 @@  - net451;netstandard2.0;netcoreapp3.1 + net462;netstandard2.0;netcoreapp3.1 netstandard2.0;netcoreapp3.1 Joveler.DynLoader Joveler.DynLoader @@ -21,7 +21,7 @@ Supports Windows, Linux, and macOS. - + From ee8d12ca5c856e00d2fa74260b1281788815a009 Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Sun, 6 Aug 2023 19:33:53 +0900 Subject: [PATCH 03/10] Update USAGE.md --- USAGE.md | 103 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/USAGE.md b/USAGE.md index bcf70f2..6bd2c79 100644 --- a/USAGE.md +++ b/USAGE.md @@ -2,16 +2,16 @@ `Joveler.DynLoader` is a cross-platform native dynamic library loader for .NET. It allows developers to create a wrapper of native C libraries easily. -The library provide two abstract class, [DynLoaderBase](#DynLoaderBase) and [LoadManagerBase](#LoadManagerBase). +The library provides two abstract class, [DynLoaderBase](#DynLoaderBase) and [LoadManagerBase](#LoadManagerBase). -Please also read [P/Invoke Tips from DynLoader](#Tips) for your easy P/Invoke life. +Please also read [P/Invoke Tips from DynLoader](#Tips) for easy P/Invoke life. ## Getting Started -To use DynLoader, you should know about two classes. +To use DynLoader, you should learn about two main classes. -| Class | 역할 | -|--------------|------| +| Class | Description | +|--------------|-------------| | [DynLoaderBase](#DynLoaderBase) | Scaffold of a native library wrapper. | | [LoadManagerBase](#LoadManagerBase) | Manages `DynLoaderBase` singleton instance. | @@ -37,7 +37,7 @@ Follow these steps to create a wrapper of a native library. Follow these steps to use a wrapper library. -1. Make an interface which calls `LoadManagerBase.GlobalInit()`. +1. Make an interface that calls `LoadManagerBase.GlobalInit()`. ```csharp public class Magic : IDisposable { @@ -59,14 +59,14 @@ Inherit [DynLoaderBase](./Joveler.DynLoader/DynLoaderBase.cs) to create a wrappe **Example Files** -[Joveler.DynLoader.Tests](./Joveler.DynLoader.Tests) contains simplified wrappers of [zlib](https://www.zlib.net) and [libmagic](http://www.darwinsys.com/file/) as examples. Freely adapt them as you need, they are released as public domain. +[Joveler.DynLoader.Tests](./Joveler.DynLoader.Tests) contains simplified wrappers of [zlib](https://www.zlib.net) and [libmagic](http://www.darwinsys.com/file/) as examples. Freely adapt them as you need, as they are released as public domain. - zlib : [SimpleZLib.cs](./Joveler.DynLoader.Tests/SimpleZLib.cs) - magic : [SimpleFileMagic.cs](./Joveler.DynLoader.Tests/SimpleFileMagic.cs) The test project also showcases per-platform delegate declarations. Read [SimplePlatform.cs](./Joveler.DynLoader.Tests/SimplePlatform.cs). -### Delegate of native functions +### Delegate native functions You need to provide a prototype of the native functions, similar to traditional [DllImport P/Invoke](https://docs.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke). @@ -105,7 +105,7 @@ public SimpleFileMagic() : base() { } ### LoadLibrary -After creating an instance of a derived class, make sure to call `LoadLibrary()` to load a native library. After then you can invoke extern native functions via delegate instances. +After creating an instance of a derived class, make sure to call `LoadLibrary()` to load a native library. After that, you can invoke extern native functions via delegate instances. `LoadLibrary(string libPath)` loads that specific native library. The parameterless version loads the default native library from the base system. @@ -119,11 +119,11 @@ Under the hood, DynLoader calls [LoadLibraryEx](https://docs.microsoft.com/en-us DynLoader follows the OS's library resolving order. On Windows, it follows [alternative library search order](https://docs.microsoft.com/en-us/windows/win32/dlls/dynamic-link-library-search-order#alternate-search-order-for-desktop-applications). On POSIX, it follows the order explained on [dlopen manual](http://man7.org/linux/man-pages/man3/dlopen.3.html). -### Methods and property to override +### Methods and properties to override ```csharp /// -/// Default filename of the native libary to use. Override only if the target platform ships with the native library. +/// Default filename of the native library to use. Override only if the target platform ships with the native library. /// /// /// Throw PlatformNotSupportedException optionally when the library is included only in some of the target platforms. @@ -144,7 +144,7 @@ protected abstract void ResetFunctions(); You must override `LoadFunctions()` with a code loading delegate of native functions. -Call `GetFuncPtr(string funcSymbol)` with a delegate type (`T`) and function symbol name (`funcSymbol`) to get a C# delegate of a symbol. Assign return value as a delegate instance you previously declared. +Call `GetFuncPtr(string funcSymbol)` with a delegate type (`T`) and function symbol name (`funcSymbol`) to get a C# delegate of a symbol. Assign the return value as a delegate instance you previously declared. The parameterless `GetFuncPtr()` is a slow but more convenient variant. It uses reflection (`typeof(T).Name`) to get a real name of `T` at runtime. If your target platform restricts the use of reflection, do not use it. @@ -169,7 +169,7 @@ protected override void LoadFunctions() Override `ResetFunctions()` when you want to explicitly clear native resources and delegate assignments. -Usually, the override of this method is not required, as the library handle is automatically cleared when the instance is disposed of. But if you need to clear delegate assignments manually, you have to implement it. +Usually, the override of this method is not required, as the library handle is automatically cleared when the instance is disposed of. But if you need to clear delegate assignments manually, you have to implement them. #### DefaultLibFileName @@ -222,7 +222,7 @@ public enum PlatformDataModel ILP32 = 2, } /// -/// Size of the long type of the platform. +/// Size of the long type of platform. /// public enum PlatformLongSize { @@ -255,7 +255,7 @@ public enum PlatformBitness /// Default unicode encoding convention of the platform. /// /// -/// Some native libraries does not follow default unicode encoding convention of the platform, so be careful. +/// Some native libraries do not follow the default Unicode encoding convention of the platform, be careful. /// public enum UnicodeConvention { @@ -278,7 +278,7 @@ public PlatformUnicodeConvention PlatformUnicodeConvention { get; } public Encoding PlatformUnicodeEncoding { get; } /// -/// Convert buffer pointer to string following platform's default encoding convention. Wrapper of Marshal.PtrToString*(). +/// Convert buffer pointer to string following the platform's default encoding convention. The wrapper of Marshal.PtrToString*(). /// /// /// Marshal.PtrToStringAnsi() use UTF-8 on POSIX. @@ -288,7 +288,7 @@ public Encoding PlatformUnicodeEncoding { get; } public string PtrToStringAuto(IntPtr ptr); /// /// -/// Convert string to buffer pointer following platform's default encoding convention. Wrapper of Marshal.StringToHGlobal*(). +/// Convert string to buffer pointer following the platform's default encoding convention. The wrapper of Marshal.StringToHGlobal*(). /// /// /// Marshal.StringToHGlobalAnsi() use UTF-8 on POSIX. @@ -296,10 +296,10 @@ public string PtrToStringAuto(IntPtr ptr); /// String to convert /// IntPtr of the string buffer. You must call Marshal.FreeHGlobal() with return value to prevent memory leak. public IntPtr StringToHGlobalAuto(string str); -/// Convert string to buffer pointer following platform's default encoding convention. Wrapper of Marshal.StringToCoTaskMem*(). +/// Convert string to buffer pointer following the platform's default encoding convention. The wrapper of Marshal.StringToCoTaskMem*(). /// /// -/// Marshal.StringToCoTaskMemAnsi() use UTF-8 on POSIX. +/// Marshal.StringToCoTaskMemAnsi() uses UTF-8 on POSIX. /// /// String to convert /// IntPtr of the string buffer. You must call Marshal.FreeCoTaskMem() with return value to prevent memory leak. @@ -324,9 +324,9 @@ In C language, the size of a data type may change per target platform. It is cal | `PlatformBitness` | `Bit32` | `Bit64` | | Size of the `UIntPtr` | 32bit | 64bit | -It is useful when to have to write different code per bitness or handle marshaling of `size_t`. +It is useful when have to write different code per bitness or handle marshaling of `size_t`. -`size_t` can be represented as `UIntPtr` in P/Invoke signatures. .NET make sure that `UIntPtr` does not store the value larger than the platform's bit size. For example, assigning `ulong.MaxValue` to `UIntPtr` on 32bit platforms invoke `OverflowException`. +`size_t` can be represented as `UIntPtr` in P/Invoke signatures. .NET makes sure that `UIntPtr` does not store the value larger than the platform's bit size. For example, assigning `ulong.MaxValue` to `UIntPtr` on 32bit platforms invoke `OverflowException`. #### PlatformUnicodeConvention, PlatformUnicodeEncoding @@ -337,9 +337,9 @@ Windows often use UTF-16 LE, while many POSIX libraries use UTF-8 without BOM. | `UnicodeConvention` | `Utf16` | `Utf8` | | `UnicodeEncoding` | `Encoding.UTF16` (UTF-16 LE) | `new UTF8Encoding(false)` (UTF-8 without BOM) | -`string PtrToStringAuto(IntPtr ptr)`, `IntPtr StringToHGlobalAuto(string str)` and `IntPtr StringToCoTaskMemAuto(string str)` is a wrapper methods of `Marshal.PtrToString*` and `Marshal.StringTo*`. They decide which encoding to use automatically depending on value of `UnicodeConvention` property. +`string PtrToStringAuto(IntPtr ptr)`, `IntPtr StringToHGlobalAuto(string str)` and `IntPtr StringToCoTaskMemAuto(string str)` is a wrapper methods of `Marshal.PtrToString*` and `Marshal.StringTo*`. They decide which encoding to use automatically depending on the value of the `UnicodeConvention` property. -**WARNING**: Native libraries may not follow the platform's default Unicode encoding convention! It is your responsibility to check which encoding library is using. For example, some cross-platform libraries which originated from the POSIX world do not use `wchar_t`, effectively using `ANSI` encoding on Windows instead of `UTF-16`. That is why you can overwrite the `UnicodeConvention` value after the class was initialized. +**WARNING**: Native libraries may not follow the platform's default Unicode encoding convention! It is your responsibility to check which encoding library is used. For example, some cross-platform libraries which originated from the POSIX world do not use `wchar_t`, effectively using `ANSI` encoding on Windows instead of `UTF-16`. That is why you can overwrite the `UnicodeConvention` value after the class was initialized. ### Disposable Pattern @@ -347,7 +347,7 @@ The class implements [Disposable Pattern](https://docs.microsoft.com/en-us/dotne ## LoadManagerBase -[LoadManagerBase](./Joveler.DynLoader/LoadManagerBase.cs) class provides a thread-safe way to manage `DynLoaderBase` singleton instance. +[LoadManagerBase](./Joveler.DynLoader/LoadManagerBase.cs) class provides a thread-safe way to manage the `DynLoaderBase` singleton instance. ### Methods and properties to override @@ -400,14 +400,14 @@ These hooks will be called before/after `CreateLoader()`/`Dispose()`. Implementi ```csharp /// -/// Allocate other external resources before CreateLoader get called. +/// Allocate other external resources before CreateLoader gets called. /// /// /// Called in GlobalInit() and GlobalInit(string libPath). /// protected virtual void PreInitHook() { } /// -/// Allocate other external resources after CreateLoader get called. +/// Allocate other external resources after CreateLoader gets called. /// /// /// Called in GlobalInit() and GlobalInit(string libPath). @@ -421,7 +421,7 @@ protected virtual void PostInitHook() { } /// protected virtual void PreDisposeHook() { } /// -/// Disallocate other external resources after disposing DynLoaderBase instance. +/// Disallocate other external resources after disposing of DynLoaderBase instance. /// /// /// Called in GlobalCleanup(). @@ -435,7 +435,7 @@ protected virtual void PostDisposeHook() { } When your app depends on user libraries, not a Win32 API, or a system call, you have to bundle the libraries yourself. -#### 1) Set `Copy to Output Directory` property of native binaries. +#### 1) Set the `Copy to Output Directory` property of native binaries. Add native library files into the project, and set `Copy to Output Directory` to `Copy if newer` in their property. @@ -448,6 +448,9 @@ Add native library files into the project, and set `Copy to Output Directory` to PreserveNewest + + PreserveNewest + ``` @@ -477,7 +480,7 @@ This method does not work on application projects. For the .NET Framework NuGet package, write an MSBuild script to handle native libraries. -**Example**: Add MSBuild script [SampleScript.netfx.targets](./Joveler.DynLoader.Tests/SampleScript.netfx.targets) to the project directory. Also add this line to .csproj: +**Example**: Add MSBuild script [SampleScript.netfx.targets](./Joveler.DynLoader.Tests/SampleScript.netfx.targets) to the project directory. Also, add this line to .csproj: ```xml ``` @@ -489,12 +492,12 @@ You can freely adapt [SampleScript.netfx.targets](./Joveler.DynLoader.Tests/Samp This is the snippet extracted from the sample .csproj file. - (1) Use `Copy to Output Directory` for application build. -- (2) Create standard NuGet package layout for .NET Core nupkg. +- (2) Create a standard NuGet package layout for .NET Core nupkg. - (3) Use MSBuild scripts for .NET Framework nupkg. ```xml - - + + x86\%(FileName)%(Extension) PreserveNewest @@ -503,6 +506,10 @@ This is the snippet extracted from the sample .csproj file. x64\%(FileName)%(Extension) PreserveNewest + + arm64\%(FileName)%(Extension) + PreserveNewest + @@ -534,6 +541,10 @@ This is the snippet extracted from the sample .csproj file. runtimes\osx-x64\native\%(FileName)%(Extension) PreserveNewest + + runtimes\osx-arm64\native\%(FileName)%(Extension) + PreserveNewest + @@ -545,6 +556,7 @@ This is the snippet extracted from the sample .csproj file. + @@ -556,14 +568,14 @@ Multiple calling conventions are used following the target OS and architecture. **Recommended Workaround**: Always set calling a convention for `x86`, as they are ignored in the other architectures. -#### x86 +#### x86/i686 On x86, you need to be cautious of calling conventions. - Windows: Win32 APIs use stdcall, while the user libraries selectively use cdecl or stdcall. - Linux, macOS: Every function uses cdecl. -Many libraries originated from the POSIX world often exclusively use cdecl. It is still valid on Windows when the library is cross-platform. In that case, specify `CallingConvention.Cdecl`. +Many libraries originating from the POSIX world often exclusively use cdecl. It is still valid on Windows when the library is cross-platform. In that case, specify `CallingConvention.Cdecl`. ```csharp [UnmanagedFunctionPointer(CallingConvention.Cdecl)] @@ -575,13 +587,13 @@ Similarly, if you are writing a wrapper of Win32 APIs on Windows, specify `Calli [UnmanagedFunctionPointer(CallingConvention.StdCall)] ``` -Some cross-platform libraries use stdcall on Windows and cdecl on POSIX (e.g., zlib), however. In that case, specify `CallingConvention.Winapi`. stdcall is automatically used on Windows while the cdecl is used on POSIX. +Some cross-platform libraries use stdcall on Windows and cdecl on POSIX (e.g., `zlibwapi.dll` build of zlib), however. In that case, specify `CallingConvention.Winapi`. stdcall is automatically used on Windows while the cdecl is used on POSIX. ```csharp [UnmanagedFunctionPointer(CallingConvention.Winapi)] ``` -#### x64 +#### x64/amd64 On x64, every platform enforces using the standardized fastcall convention. So, in theory, you do not need to care about it. @@ -600,7 +612,7 @@ Similar to x64, these platforms are known to enforce one standardized calling co `size_t` has a different size per architecture. It has the same size as the pointer size, using 4B on 32bit arch (x86, armhf) and using 8B on 64bit arch (x64, arm64). It is troublesome in cross-platform P/Invoke, as no direct counterpart exists in .NET. -You can exploit [UIntPtr](https://docs.microsoft.com/en-US/dotnet/api/system.uintptr) (or [IntPtr](https://docs.microsoft.com/en-US/dotnet/api/system.intptr)) struct to handle this problem. While the .NET runtime does not provide the direct mechanism, these struct has the same size as the platform's pointer size. Thus, we can safely use `UIntPtr` as the C# equivalent of `size_t`. You must have to take caution, though, because we want to use `UIntPtr` as a value, not an address. +You can exploit [UIntPtr](https://docs.microsoft.com/en-US/dotnet/api/system.uintptr) (or [IntPtr](https://docs.microsoft.com/en-US/dotnet/api/system.intptr)) struct to handle this problem. While the .NET runtime does not provide the direct mechanism, this struct has the same size as the platform's pointer size. Thus, we can safely use `UIntPtr` as the C# equivalent of `size_t`. You must have to take caution, though, because we want to use `UIntPtr` as a value, not an address. I recommend using `UIntPtr` instead of `IntPtr` to represent `size_t` for safety. `IntPtr` is often used as a pure pointer itself while the `UIntPtr` is rarely used. Distinguishing `UIntPtr (value)` from the `IntPtr (address)` prevents the mistakes and crashes from confusing these two. @@ -622,7 +634,7 @@ C\# 9.0 or later supports [`nint` and `nuint`](https://docs.microsoft.com/en-us/ ```csharp [UnmanagedFunctionPointer(CallingConvention.Cdecl)] -internal delegate UIntPtr LZ4F_getFrameInfo( +internal delegate nuint LZ4F_getFrameInfo( IntPtr dctx, FrameInfo frameInfoPtr, IntPtr srcCapacity, @@ -634,9 +646,9 @@ internal static LZ4F_getFrameInfo GetFrameInfo; **Recommended Workaround**: If the native library use `long` in its APIs, declare two sets of delegates, the LP64 model for POSIX 64bit and LLP64 for the other. -In 64bit, `long` can have different sizes per target OS and architecture. Windows use the LLP64 data model (long is 32bit) on 64bit arch, while the POSIX use LP64 (long is 64bit). +In 64bit, `long` can have different sizes per target OS and architecture. Windows uses the LLP64 data model (long is 32bit) on 64bit arch, while the POSIX use LP64 (long is 64bit). -If a native library uses `long` in the exported functions, there is no simple solution. You would have to prepare two sets of delegates, and make sure you assign and call the right delegate per target architecture and OS. +If a native library uses `long` in the exported functions, there is no simple solution. You would have to prepare two sets of delegates and make sure you assign and call the right delegate per target architecture and OS. Some libraries with a long history (e.g., zlib) have this problem. Fortunately, many modern cross-platform libraries tend to use types of `` or similar so that they can ensure stable type size across platforms. @@ -644,9 +656,9 @@ Some libraries with a long history (e.g., zlib) have this problem. Fortunately, ### String encoding -**Recommended Workaround**: Declare two sets of delegates, the UTF-16 model for POSIX 64bit and LLP64 for the other. +**Recommended Workaround**: Use the `IntPtr` type, and convert it to/from a string in runtime with helper methods. -Different platforms have different charset and encoding conventions, and native libraries often follow it. +Different platforms have different charset and encoding conventions, and native libraries often follow them. - Windows: `UTF-16`, `ANSI` - POSIX: `UTF-8` @@ -654,13 +666,18 @@ Different platforms have different charset and encoding conventions, and native Look for which data type the library used for strings. - `char*`: `ANSI` on Windows and `UTF-8` on POSIX. Mostly used in POSIX libraries. -- `wchar_t*`: `UTF-16` on Windows and `UTF-32`on POSIX. Windows libraries use it but rarely in POSIX libraries. +- `wchar_t*`: `UTF-16` on Windows and `UTF-32` on POSIX. Windows libraries use it but rarely in POSIX libraries. - `tchar*`: `UTF-16` on Windows and `UTF-8` on POSIX. Windows libraries and some cross-platform POSIX libraries use it. Fortunately, you do not need to duplicate structs in most cases. Put `IntPtr` in place of a string field, then return string as a property using `DynLoaderBase.StringTo*Auto()` and `DynLoaderBase.PtrToStringAuto()` helper methods. **Example** +This example shows two solutions: + +- Declaring two sets of delegates +- Use `IntPtr` and convert them in runtime. + ```csharp internal class Utf8d { From 7972bb35516f3af3eba3a0668a7b4674686870b5 Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Sun, 6 Aug 2023 20:18:20 +0900 Subject: [PATCH 04/10] Update NuGet packages --- Joveler.DynLoader.Tests/TestSetup.cs | 6 +++--- Joveler.DynLoader/Joveler.DynLoader.csproj | 11 +++++------ Joveler.DynLoader/NativeMethods.cs | 1 - 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/Joveler.DynLoader.Tests/TestSetup.cs b/Joveler.DynLoader.Tests/TestSetup.cs index 4b71d66..e75a1c3 100644 --- a/Joveler.DynLoader.Tests/TestSetup.cs +++ b/Joveler.DynLoader.Tests/TestSetup.cs @@ -152,9 +152,9 @@ public static void AssemblyCleanup() ImplicitMagic?.Dispose(); PlatformLib?.Dispose(); } -#endregion + #endregion -#region TestHelper + #region TestHelper public class TestHelper { public static string GetProgramAbsolutePath() @@ -165,6 +165,6 @@ public static string GetProgramAbsolutePath() return path; } } -#endregion + #endregion } } diff --git a/Joveler.DynLoader/Joveler.DynLoader.csproj b/Joveler.DynLoader/Joveler.DynLoader.csproj index 965f371..e962e12 100644 --- a/Joveler.DynLoader/Joveler.DynLoader.csproj +++ b/Joveler.DynLoader/Joveler.DynLoader.csproj @@ -1,27 +1,26 @@  - net462;netstandard2.0;netcoreapp3.1 + net46;netstandard2.0;netcoreapp3.1 netstandard2.0;netcoreapp3.1 Joveler.DynLoader Joveler.DynLoader - 2.1.1 + 2.2.0 Hajin Jang Joveler Cross-platform native dynamic library loader for .NET. Provides advanced P/Invoke functionality using NativeLibrary, LoadLibrary and libdl. Supports Windows, Linux, and macOS. - Copyright (C) 2019-2022 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang MIT https://github.com/ied206/Joveler.DynLoader images\Logo.png https://github.com/ied206/Joveler.DynLoader - - Official support for ARM64 macOS. -- Unify .NET Framework 4.5.1 codebase and .NET Standard 2.0 codebase. + - Allow passing arbitrary objects to GlobalInit(). native pinvoke interop dynamic library loader dll so dylib - + diff --git a/Joveler.DynLoader/NativeMethods.cs b/Joveler.DynLoader/NativeMethods.cs index 3f277e5..f03ac53 100644 --- a/Joveler.DynLoader/NativeMethods.cs +++ b/Joveler.DynLoader/NativeMethods.cs @@ -24,7 +24,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ using System; -using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace Joveler.DynLoader From 46d866c09d20378df43006c2a62dc24ab0d20283 Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Sun, 6 Aug 2023 20:18:59 +0900 Subject: [PATCH 05/10] Update NuGet packages (2) --- Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj b/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj index fd418d0..1aafcad 100644 --- a/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj +++ b/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj @@ -17,13 +17,13 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + From 517b20c71c5f5fef86c605703d211161eccd7dcb Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Mon, 7 Aug 2023 22:52:45 +0900 Subject: [PATCH 06/10] Add LoadData support to LoadLibrary --- .gitignore | 9 +- Joveler.DynLoader.Tests/GhostErrorTests.cs | 4 +- .../Joveler.DynLoader.Tests.csproj | 9 +- .../PlatformConventionTests.cs | 2 +- .../SimpleFIleMagicManager.cs | 7 +- .../SimpleFileMagicTests.cs | 2 +- .../SimplePlatformTests.cs | 2 +- Joveler.DynLoader.Tests/SimpleZLib.cs | 126 +++++++++++++++--- Joveler.DynLoader.Tests/SimpleZLibManager.cs | 7 +- Joveler.DynLoader.Tests/SimpleZLibTests.cs | 44 ++++-- Joveler.DynLoader.Tests/TestSetup.cs | 48 ++++--- .../runtimes/win-arm64/native/zlib1.dll | Bin 0 -> 92672 bytes .../runtimes/win-x64/native/zlib1.dll | Bin 0 -> 116736 bytes .../runtimes/win-x86/native/zlib1.dll | Bin 0 -> 105984 bytes Joveler.DynLoader/DynLoaderBase.cs | 47 ++++++- Joveler.DynLoader/LoadManagerBase.cs | 27 +++- 16 files changed, 264 insertions(+), 70 deletions(-) create mode 100644 Joveler.DynLoader.Tests/runtimes/win-arm64/native/zlib1.dll create mode 100644 Joveler.DynLoader.Tests/runtimes/win-x64/native/zlib1.dll create mode 100644 Joveler.DynLoader.Tests/runtimes/win-x86/native/zlib1.dll diff --git a/.gitignore b/.gitignore index d63c2a7..b17da51 100644 --- a/.gitignore +++ b/.gitignore @@ -38,10 +38,10 @@ bld/ [Ll]og/ # Do not ignore Precompiled directory -!/**/Precompiled/x86/ -!/**/Precompiled/x64/ -!/**/Precompiled/armhf/ -!/**/Precompiled/arm64/ +!/**/runtimes/**/native/ + +# Thumbs.db +Thumbs.db # macOS DS_Store guard .DS_Store @@ -173,6 +173,7 @@ AutoTest.Net/ # Installshield output folder [Ee]xpress/ + # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT diff --git a/Joveler.DynLoader.Tests/GhostErrorTests.cs b/Joveler.DynLoader.Tests/GhostErrorTests.cs index d4117da..644ac97 100644 --- a/Joveler.DynLoader.Tests/GhostErrorTests.cs +++ b/Joveler.DynLoader.Tests/GhostErrorTests.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License @@ -59,7 +59,7 @@ public void LoadFunctionError() try { GhostFunction lib = new GhostFunction(); - lib.LoadLibrary(TestSetup.PackagedZLibPath); + lib.LoadLibrary(TestSetup.PackagedZLibPathStdcall); } catch (EntryPointNotFoundException e) { diff --git a/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj b/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj index 1aafcad..a6589b2 100644 --- a/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj +++ b/Joveler.DynLoader.Tests/Joveler.DynLoader.Tests.csproj @@ -64,8 +64,8 @@ - - + + runtimes\win-x86\native\%(FileName)%(Extension) PreserveNewest @@ -94,7 +94,10 @@ runtimes\osx-x64\native\%(FileName)%(Extension) PreserveNewest + + runtimes\osx-arm64\native\%(FileName)%(Extension) + PreserveNewest + - diff --git a/Joveler.DynLoader.Tests/PlatformConventionTests.cs b/Joveler.DynLoader.Tests/PlatformConventionTests.cs index 663d058..68373c3 100644 --- a/Joveler.DynLoader.Tests/PlatformConventionTests.cs +++ b/Joveler.DynLoader.Tests/PlatformConventionTests.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2020 Hajin Jang + Copyright (C) 2020-2023 Hajin Jang Licensed under MIT License. MIT License diff --git a/Joveler.DynLoader.Tests/SimpleFIleMagicManager.cs b/Joveler.DynLoader.Tests/SimpleFIleMagicManager.cs index 3ec61ce..624b66d 100644 --- a/Joveler.DynLoader.Tests/SimpleFIleMagicManager.cs +++ b/Joveler.DynLoader.Tests/SimpleFIleMagicManager.cs @@ -1,4 +1,9 @@ -using System; +/* + Written by Hajin Jang. + Released under public domain. +*/ + +using System; namespace Joveler.DynLoader.Tests { diff --git a/Joveler.DynLoader.Tests/SimpleFileMagicTests.cs b/Joveler.DynLoader.Tests/SimpleFileMagicTests.cs index c13b78c..e1adc5f 100644 --- a/Joveler.DynLoader.Tests/SimpleFileMagicTests.cs +++ b/Joveler.DynLoader.Tests/SimpleFileMagicTests.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License diff --git a/Joveler.DynLoader.Tests/SimplePlatformTests.cs b/Joveler.DynLoader.Tests/SimplePlatformTests.cs index 67fc668..1f950ce 100644 --- a/Joveler.DynLoader.Tests/SimplePlatformTests.cs +++ b/Joveler.DynLoader.Tests/SimplePlatformTests.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License diff --git a/Joveler.DynLoader.Tests/SimpleZLib.cs b/Joveler.DynLoader.Tests/SimpleZLib.cs index 2c8cd35..20b1242 100644 --- a/Joveler.DynLoader.Tests/SimpleZLib.cs +++ b/Joveler.DynLoader.Tests/SimpleZLib.cs @@ -8,6 +8,12 @@ Released under public domain. namespace Joveler.DynLoader.Tests { + public class SimpleZLibLoadData + { + public bool IsWindowsStdcall { get; set; } = true; + public bool HasScanned { get; set; } = false; + } + /// /// Sample representation of zlib, includes only adler32 and crc32 checksum /// @@ -30,39 +36,123 @@ protected override string DefaultLibFileName throw new PlatformNotSupportedException(); } } + + private bool _isWindowsStdcall = true; + #endregion + + #region Stdcall and Cdecl + internal Stdcall _stdcall = new Stdcall(); + internal Cdecl _cdecl = new Cdecl(); + #endregion + + #region ParseCustomData + protected override void ParseLoadData(object data) + { + if (!(data is SimpleZLibLoadData loadData)) + return; + + _isWindowsStdcall = loadData.IsWindowsStdcall; + Console.WriteLine($"libPath = {LibPath}"); + Console.WriteLine($"isWindowsStdcall = {_isWindowsStdcall}"); + } #endregion #region LoadFunctions, ResetFunctions /// protected override void LoadFunctions() { - Adler32 = GetFuncPtr(nameof(adler32)); - Crc32 = GetFuncPtr(nameof(crc32)); - ZLibVersionPtr = GetFuncPtr(); + if (_isWindowsStdcall) + { + _stdcall.Adler32 = GetFuncPtr(nameof(Stdcall.adler32)); + _stdcall.Crc32 = GetFuncPtr(nameof(Stdcall.crc32)); + _stdcall.ZLibVersionPtr = GetFuncPtr(); + } + else + { + _cdecl.Adler32 = GetFuncPtr(nameof(Cdecl.adler32)); + _cdecl.Crc32 = GetFuncPtr(nameof(Cdecl.crc32)); + _cdecl.ZLibVersionPtr = GetFuncPtr(); + } } /// protected override void ResetFunctions() { - Adler32 = null; - Crc32 = null; - ZLibVersionPtr = null; + if (_isWindowsStdcall) + { + _stdcall.Adler32 = null; + _stdcall.Crc32 = null; + _stdcall.ZLibVersionPtr = null; + } + else + { + _cdecl.Adler32 = null; + _cdecl.Crc32 = null; + _cdecl.ZLibVersionPtr = null; + } } #endregion #region zlib Function Pointers - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - public unsafe delegate uint adler32(uint adler, byte* buf, uint len); - public adler32 Adler32; - - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - public unsafe delegate uint crc32(uint crc, byte* buf, uint len); - public crc32 Crc32; - - [UnmanagedFunctionPointer(CallingConvention.Winapi)] - public delegate IntPtr zlibVersion(); - private zlibVersion ZLibVersionPtr; - public string ZLibVersion() => Marshal.PtrToStringAnsi(ZLibVersionPtr()); + public unsafe uint Adler32(uint adler, byte* buf, uint len) + { + if (_isWindowsStdcall) + return _stdcall.Adler32(adler, buf, len); + else + return _cdecl.Adler32(adler, buf, len); + } + + public unsafe uint Crc32(uint crc, byte* buf, uint len) + { + if (_isWindowsStdcall) + return _stdcall.Crc32(crc, buf, len); + else + return _cdecl.Crc32(crc, buf, len); + } + + public string ZLibVersion() + { + IntPtr strPtr = IntPtr.Zero; + if (_isWindowsStdcall) + strPtr = _stdcall.ZLibVersionPtr(); + else + strPtr = _cdecl.ZLibVersionPtr(); + return Marshal.PtrToStringAnsi(strPtr); + } + + internal class Stdcall + { + private const CallingConvention CallConv = CallingConvention.Winapi; + + [UnmanagedFunctionPointer(CallConv)] + public unsafe delegate uint adler32(uint adler, byte* buf, uint len); + public adler32 Adler32; + + [UnmanagedFunctionPointer(CallConv)] + public unsafe delegate uint crc32(uint crc, byte* buf, uint len); + public crc32 Crc32; + + [UnmanagedFunctionPointer(CallConv)] + public delegate IntPtr zlibVersion(); + internal zlibVersion ZLibVersionPtr; + + } + internal class Cdecl + { + private const CallingConvention CallConv = CallingConvention.Cdecl; + + [UnmanagedFunctionPointer(CallConv)] + public unsafe delegate uint adler32(uint adler, byte* buf, uint len); + public adler32 Adler32; + + [UnmanagedFunctionPointer(CallConv)] + public unsafe delegate uint crc32(uint crc, byte* buf, uint len); + public crc32 Crc32; + + [UnmanagedFunctionPointer(CallConv)] + public delegate IntPtr zlibVersion(); + internal zlibVersion ZLibVersionPtr; + } #endregion } } diff --git a/Joveler.DynLoader.Tests/SimpleZLibManager.cs b/Joveler.DynLoader.Tests/SimpleZLibManager.cs index 2d2b839..7588719 100644 --- a/Joveler.DynLoader.Tests/SimpleZLibManager.cs +++ b/Joveler.DynLoader.Tests/SimpleZLibManager.cs @@ -1,4 +1,9 @@ -namespace Joveler.DynLoader.Tests +/* + Written by Hajin Jang. + Released under public domain. +*/ + +namespace Joveler.DynLoader.Tests { public class SimpleZLibManager : LoadManagerBase { diff --git a/Joveler.DynLoader.Tests/SimpleZLibTests.cs b/Joveler.DynLoader.Tests/SimpleZLibTests.cs index 3c7c156..6f51690 100644 --- a/Joveler.DynLoader.Tests/SimpleZLibTests.cs +++ b/Joveler.DynLoader.Tests/SimpleZLibTests.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License @@ -38,7 +38,7 @@ public class SimpleZLibTests [ClassInitialize] public static void Init(TestContext _) { - _zlibs = new SimpleZLib[] { TestSetup.ExplicitZLib, TestSetup.ImplicitZLib }; + _zlibs = new SimpleZLib[] { TestSetup.ExplicitStdcallZLib, TestSetup.ExplicitCdeclZLib, TestSetup.ImplicitZLib }; _zlibs = _zlibs.Where(z => z != null).ToArray(); } @@ -105,9 +105,9 @@ public void Version() } [TestMethod] - public void CreateDispose() + public void StdcallCreateDispose() { - string libPath = TestSetup.PackagedZLibPath; + string libPath = TestSetup.PackagedZLibPathStdcall; using (SimpleZLib zlib = new SimpleZLib()) { zlib.LoadLibrary(libPath); @@ -116,17 +116,43 @@ public void CreateDispose() } [TestMethod] - public void Manager() + public void CdeclCreateDispose() { - string libPath = TestSetup.PackagedZLibPath; + string libPath = TestSetup.PackagedZLibPathCdecl; + using (SimpleZLib zlib = new SimpleZLib()) + { + zlib.LoadLibrary(libPath); + zlib.ZLibVersion(); + } + } + + [TestMethod] + public void StdcallManager() + { + string libPath = TestSetup.PackagedZLibPathStdcall; + ManagerTemplate(libPath, true); + } + + [TestMethod] + public void CdeclManager() + { + string libPath = TestSetup.PackagedZLibPathCdecl; + ManagerTemplate(libPath, false); + } + private void ManagerTemplate(string libPath, bool isWindowsStdcall) + { SimpleZLibManager manager = new SimpleZLibManager(); + SimpleZLibLoadData loadData = new SimpleZLibLoadData() + { + IsWindowsStdcall = isWindowsStdcall, + }; bool dupInitGuard = false; - manager.GlobalInit(libPath); + manager.GlobalInit(libPath, loadData); try { - manager.GlobalInit(); + manager.GlobalInit(loadData); } catch (InvalidOperationException) { @@ -134,7 +160,7 @@ public void Manager() } Assert.IsTrue(dupInitGuard); - manager.Lib.ZLibVersion(); + Console.WriteLine(manager.Lib.ZLibVersion()); bool dupCleanGuard = false; manager.GlobalCleanup(); diff --git a/Joveler.DynLoader.Tests/TestSetup.cs b/Joveler.DynLoader.Tests/TestSetup.cs index e75a1c3..5bc1859 100644 --- a/Joveler.DynLoader.Tests/TestSetup.cs +++ b/Joveler.DynLoader.Tests/TestSetup.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License @@ -34,8 +34,10 @@ namespace Joveler.DynLoader.Tests public class TestSetup { public static string SampleDir { get; private set; } - public static string PackagedZLibPath { get; private set; } - public static SimpleZLib ExplicitZLib { get; private set; } + public static string PackagedZLibPathStdcall { get; private set; } + public static string PackagedZLibPathCdecl { get; private set; } + public static SimpleZLib ExplicitStdcallZLib { get; private set; } + public static SimpleZLib ExplicitCdeclZLib { get; private set; } public static SimpleZLib ImplicitZLib { get; private set; } public static string PackagedMagicPath { get; private set; } public static SimpleFileMagic ExplicitMagic { get; private set; } @@ -52,14 +54,13 @@ public static void AssemblyInitalize(TestContext ctx) string libBaseDir = Path.GetFullPath(Path.Combine(TestHelper.GetProgramAbsolutePath(), "..", "..", "..")); #endif - const string zlibDllName = "zlibwapi.dll"; + const string zlibStdcallDllName = "zlibwapi.dll"; + const string zlibCdeclDllName = "zlib1.dll"; const string magicDllName = "libmagic-1.dll"; -#if NETCOREAPP const string zlibSoName = "libz.so"; const string zlibDylibName = "libz.dylib"; const string magicSoName = "libmagic.so"; const string magicDylibName = "libmagic.dylib"; -#endif string arch = null; switch (RuntimeInformation.ProcessArchitecture) @@ -80,12 +81,12 @@ public static void AssemblyInitalize(TestContext ctx) bool implicitLoadZLib = false; bool implicitLoadMagic = false; - bool implicitLoadPlataform = false; + bool implicitLoadPlatform = false; string libDir; #if NETFRAMEWORK libDir = Path.Combine(libBaseDir, arch); -#elif NETCOREAPP +#else libDir = Path.Combine(libBaseDir, "runtimes"); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) libDir = Path.Combine(libDir, "win-"); @@ -95,33 +96,40 @@ public static void AssemblyInitalize(TestContext ctx) libDir = Path.Combine(libDir, "osx-"); libDir += arch; libDir = Path.Combine(libDir, "native"); +#endif if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) -#endif { - PackagedZLibPath = Path.Combine(libDir, zlibDllName); + PackagedZLibPathStdcall = Path.Combine(libDir, zlibStdcallDllName); + PackagedZLibPathCdecl = Path.Combine(libDir, zlibCdeclDllName); PackagedMagicPath = Path.Combine(libDir, magicDllName); - implicitLoadPlataform = true; + implicitLoadPlatform = true; } -#if NETCOREAPP else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { - PackagedZLibPath = Path.Combine(libDir, zlibSoName); + PackagedZLibPathStdcall = Path.Combine(libDir, zlibSoName); PackagedMagicPath = Path.Combine(libDir, magicSoName); implicitLoadZLib = true; implicitLoadMagic = true; - implicitLoadPlataform = true; + implicitLoadPlatform = true; } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) { - PackagedZLibPath = Path.Combine(libDir, zlibDylibName); + PackagedZLibPathStdcall = Path.Combine(libDir, zlibDylibName); PackagedMagicPath = Path.Combine(libDir, magicDylibName); implicitLoadZLib = true; } -#endif - ExplicitZLib = new SimpleZLib(); - ExplicitZLib.LoadLibrary(PackagedZLibPath); + ExplicitStdcallZLib = new SimpleZLib(); + ExplicitStdcallZLib.LoadLibrary(PackagedZLibPathStdcall, new SimpleZLibLoadData() + { + IsWindowsStdcall = true, + }); + ExplicitCdeclZLib = new SimpleZLib(); + ExplicitCdeclZLib.LoadLibrary(PackagedZLibPathCdecl, new SimpleZLibLoadData() + { + IsWindowsStdcall = false, + }); if (implicitLoadZLib) { ImplicitZLib = new SimpleZLib(); @@ -136,7 +144,7 @@ public static void AssemblyInitalize(TestContext ctx) ImplicitMagic.LoadLibrary(); } - if (implicitLoadPlataform) + if (implicitLoadPlatform) { PlatformLib = new SimplePlatform(); PlatformLib.LoadLibrary(); @@ -146,7 +154,7 @@ public static void AssemblyInitalize(TestContext ctx) [AssemblyCleanup] public static void AssemblyCleanup() { - ExplicitZLib?.Dispose(); + ExplicitStdcallZLib?.Dispose(); ImplicitZLib?.Dispose(); ExplicitMagic?.Dispose(); ImplicitMagic?.Dispose(); diff --git a/Joveler.DynLoader.Tests/runtimes/win-arm64/native/zlib1.dll b/Joveler.DynLoader.Tests/runtimes/win-arm64/native/zlib1.dll new file mode 100644 index 0000000000000000000000000000000000000000..cebffed4bb6db881ff718297b0a89e100665de96 GIT binary patch literal 92672 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 z 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 lY=sVdHVGaTACa^n` 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 Nof+q6?tiNW{u5Mc6{!FK literal 0 HcmV?d00001 diff --git a/Joveler.DynLoader.Tests/runtimes/win-x64/native/zlib1.dll b/Joveler.DynLoader.Tests/runtimes/win-x64/native/zlib1.dll new file mode 100644 index 0000000000000000000000000000000000000000..134c6979a8703ee37fc7e0fcf029aa05d0672de4 GIT binary patch literal 116736 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 J@xQzT{u@u#rHKFl literal 0 HcmV?d00001 diff --git a/Joveler.DynLoader.Tests/runtimes/win-x86/native/zlib1.dll b/Joveler.DynLoader.Tests/runtimes/win-x86/native/zlib1.dll new file mode 100644 index 0000000000000000000000000000000000000000..b1ab8dd7264b7026d19145a649aa69f8b7f2ffa0 GIT binary patch literal 105984 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%0D`6HW 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 /// Create an instance of DynLoaderBase and set platform conventions. @@ -129,7 +133,7 @@ private void GlobalCleanup() /// public void LoadLibrary() { - LoadLibrary(null); + LoadLibrary(null, null); } /// @@ -137,6 +141,25 @@ public void LoadLibrary() /// /// A native library file to load. public void LoadLibrary(string libPath) + { + LoadLibrary(libPath, null); + } + + /// + /// Load a native dynamic library from a path of `DefaultLibFileName`. + /// + /// Custom object to be passed to . + public void LoadLibrary(object data) + { + LoadLibrary(null, data); + } + + /// + /// Load a native dynamic library from a given path. + /// + /// A native library file to load. + /// Custom object to be passed to . + public void LoadLibrary(string libPath, object data) { // Should DynLoaderBase use default library filename? if (libPath == null) @@ -146,9 +169,13 @@ public void LoadLibrary(string libPath) libPath = DefaultLibFileName; } + LibPath = libPath; + + // Parse custom data + ParseLoadData(data); // Use .NET Core's NativeLibrary when available -#if NETCOREAPP3_1 +#if NETCOREAPP // NET's NativeLibrary will throw DllNotFoundException by itself. // No need to check _hModule.IsInvalid here. _hModule = new NetSafeLibHandle(libPath); @@ -262,7 +289,7 @@ protected T GetFuncPtr() where T : Delegate protected T GetFuncPtr(string funcSymbol) where T : Delegate { IntPtr funcPtr; -#if NETCOREAPP3_1 +#if NETCOREAPP funcPtr = NativeLibrary.GetExport(_hModule.DangerousGetHandle(), funcSymbol); #else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -327,6 +354,16 @@ protected T GetFuncPtr(string funcSymbol) where T : Delegate protected abstract string DefaultLibFileName { get; } #endregion + #region (virtual) ParseLoadData + /// + /// Parse custom object passed into . + /// + /// Custom object to be passed to . + protected virtual void ParseLoadData(object data) + { + } + #endregion + #region (abstract) LoadFunctions, ResetFunctions /// /// Load native functions with a GetFuncPtr. Called in the constructors. diff --git a/Joveler.DynLoader/LoadManagerBase.cs b/Joveler.DynLoader/LoadManagerBase.cs index 976f036..0107141 100644 --- a/Joveler.DynLoader/LoadManagerBase.cs +++ b/Joveler.DynLoader/LoadManagerBase.cs @@ -148,23 +148,42 @@ protected virtual void PostDisposeHook() { } /// public void GlobalInit() { - GlobalInit(null); + GlobalInit(null, null); } /// /// Create DynLoaderBase singleton instance in a thread-safe way. /// - /// + /// A native library file to load. public void GlobalInit(string libPath) + { + GlobalInit(libPath, null); + } + + /// + /// Create DynLoaderBase singleton instance in a thread-safe way. + /// + /// Custom object to be passed to . + public void GlobalInit(object data) + { + GlobalInit(null, data); + } + + /// + /// Create DynLoaderBase singleton instance in a thread-safe way. + /// + /// A native library file to load. + /// Custom object to be passed to . + public void GlobalInit(string libPath, object data) { lock (_loadLock) { if (Lib != null) throw new InvalidOperationException(ErrorMsgAlreadyLoaded); - PreInitHook(); Lib = CreateLoader(); - Lib.LoadLibrary(libPath); + PreInitHook(); + Lib.LoadLibrary(libPath, data); PostInitHook(); } } From 3256870d101fb97ebe5a55cf386086b1fb1c3939 Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Mon, 7 Aug 2023 22:56:59 +0900 Subject: [PATCH 07/10] Add LogEnvironment tests --- Joveler.DynLoader.Tests/TestSetup.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Joveler.DynLoader.Tests/TestSetup.cs b/Joveler.DynLoader.Tests/TestSetup.cs index 5bc1859..76ffe63 100644 --- a/Joveler.DynLoader.Tests/TestSetup.cs +++ b/Joveler.DynLoader.Tests/TestSetup.cs @@ -27,6 +27,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE using System; using System.IO; using System.Runtime.InteropServices; +using System.Text; namespace Joveler.DynLoader.Tests { @@ -174,5 +175,16 @@ public static string GetProgramAbsolutePath() } } #endregion + + #region LogEnvironment + [TestMethod] + public void LogEnvironment() + { + StringBuilder b = new StringBuilder(); + b.AppendLine($"OS = {RuntimeInformation.OSDescription} {RuntimeInformation.OSArchitecture}"); + b.AppendLine($"Dotnet Runtime = {RuntimeInformation.FrameworkDescription} {RuntimeInformation.ProcessArchitecture}"); + Console.WriteLine(b.ToString()); + } + #endregion } } From 33da13fdea10ceecffe3037f3fe3d8f26b4f98ce Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Mon, 7 Aug 2023 23:03:51 +0900 Subject: [PATCH 08/10] Fix broken linux-arm tests --- Joveler.DynLoader.Tests/TestSetup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Joveler.DynLoader.Tests/TestSetup.cs b/Joveler.DynLoader.Tests/TestSetup.cs index 76ffe63..ea768f9 100644 --- a/Joveler.DynLoader.Tests/TestSetup.cs +++ b/Joveler.DynLoader.Tests/TestSetup.cs @@ -73,7 +73,7 @@ public static void AssemblyInitalize(TestContext ctx) arch = "x64"; break; case Architecture.Arm: - arch = "armhf"; + arch = "arm"; break; case Architecture.Arm64: arch = "arm64"; From 29bf4e3143eaa072a6a3efd021613a7f0abed677 Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Tue, 8 Aug 2023 01:24:03 +0900 Subject: [PATCH 09/10] Add HasFuncSymbol, GetFuncRawPtr to DynLoaderBase --- Joveler.DynLoader.Tests/SimpleZLib.cs | 9 ++++- Joveler.DynLoader.Tests/SimpleZLibTests.cs | 4 ++ Joveler.DynLoader/DynLoaderBase.cs | 45 +++++++++++++++++++--- Joveler.DynLoader/LoadManagerBase.cs | 4 +- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/Joveler.DynLoader.Tests/SimpleZLib.cs b/Joveler.DynLoader.Tests/SimpleZLib.cs index 20b1242..08720ee 100644 --- a/Joveler.DynLoader.Tests/SimpleZLib.cs +++ b/Joveler.DynLoader.Tests/SimpleZLib.cs @@ -11,7 +11,6 @@ namespace Joveler.DynLoader.Tests public class SimpleZLibLoadData { public bool IsWindowsStdcall { get; set; } = true; - public bool HasScanned { get; set; } = false; } /// @@ -38,6 +37,10 @@ protected override string DefaultLibFileName } private bool _isWindowsStdcall = true; + + public bool HasUnknownSymbol { get; private set; } = true; + public bool HasCrc32Symbol { get; private set; } = false; + public IntPtr DeflateRawPtr { get; private set; } = IntPtr.Zero; #endregion #region Stdcall and Cdecl @@ -61,6 +64,10 @@ protected override void ParseLoadData(object data) /// protected override void LoadFunctions() { + HasUnknownSymbol = HasFuncSymbol("UnknownSymbol"); + HasCrc32Symbol = HasFuncSymbol(nameof(Cdecl.crc32)); + DeflateRawPtr = GetRawFuncPtr("deflate"); + if (_isWindowsStdcall) { _stdcall.Adler32 = GetFuncPtr(nameof(Stdcall.adler32)); diff --git a/Joveler.DynLoader.Tests/SimpleZLibTests.cs b/Joveler.DynLoader.Tests/SimpleZLibTests.cs index 6f51690..c6473e4 100644 --- a/Joveler.DynLoader.Tests/SimpleZLibTests.cs +++ b/Joveler.DynLoader.Tests/SimpleZLibTests.cs @@ -162,6 +162,10 @@ private void ManagerTemplate(string libPath, bool isWindowsStdcall) Console.WriteLine(manager.Lib.ZLibVersion()); + Assert.IsFalse(manager.Lib.HasUnknownSymbol); + Assert.IsTrue(manager.Lib.HasCrc32Symbol); + Assert.AreNotEqual(IntPtr.Zero, manager.Lib.DeflateRawPtr); + bool dupCleanGuard = false; manager.GlobalCleanup(); try diff --git a/Joveler.DynLoader/DynLoaderBase.cs b/Joveler.DynLoader/DynLoaderBase.cs index c369ab5..726b914 100644 --- a/Joveler.DynLoader/DynLoaderBase.cs +++ b/Joveler.DynLoader/DynLoaderBase.cs @@ -171,7 +171,7 @@ public void LoadLibrary(string libPath, object data) } LibPath = libPath; - // Parse custom data + // Parse custom load data ParseLoadData(data); // Use .NET Core's NativeLibrary when available @@ -199,7 +199,7 @@ public void LoadLibrary(string libPath, object data) if (_hModule.IsInvalid) { // Sample message of .NET Core 3.1's NativeLoader: - // Unable to load DLL 'x64\zlibwapi.dll' or one of its dependencies: The specified module could not be found. (0x8007007E). + // Unable to load DLL 'x64\zlibwapi.dll' or one of its dependencies: The specified module could not be found. (0x8007007E) // Unable to load DLL 'ᄒᆞᆫ글ḀḘ韓國Ghost.dll' or one of its dependencies: 지정된 모듈을 찾을 수 없습니다. (0x8007007E) string exceptMsg = $"Unable to load DLL '{libPath}' or one of its dependencies"; int errorCode = Marshal.GetLastWin32Error(); @@ -267,13 +267,14 @@ public void LoadLibrary(string libPath, object data) private bool Loaded => _hModule != null && !_hModule.IsInvalid; #endregion - #region (protected) GetFuncPtr + #region (protected) GetFuncPtr, GetRawFuncPtr, HasFuncSymbol /// /// Get a delegate of a native function from a library. /// The method will use name of the given delegate T as function symbol. /// /// Delegate type of a native function. /// Delegate instance of a native function. + /// Throwen if the given function symbol was not found. protected T GetFuncPtr() where T : Delegate { string funcSymbol = typeof(T).Name; @@ -286,6 +287,7 @@ protected T GetFuncPtr() where T : Delegate /// Delegate type of a native function. /// Name of the exported function symbol. /// Delegate instance of a native function. + /// Throwen if the given function symbol was not found. protected T GetFuncPtr(string funcSymbol) where T : Delegate { IntPtr funcPtr; @@ -315,7 +317,6 @@ protected T GetFuncPtr(string funcSymbol) where T : Delegate throw new EntryPointNotFoundException($"{exceptMsg}."); else throw new EntryPointNotFoundException($"{exceptMsg}: {errorMsg}"); - } } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -338,9 +339,42 @@ protected T GetFuncPtr(string funcSymbol) where T : Delegate throw new PlatformNotSupportedException(); } #endif - return Marshal.GetDelegateForFunctionPointer(funcPtr); } + + protected IntPtr GetRawFuncPtr(string funcSymbol) + { + IntPtr funcPtr = IntPtr.Zero; +#if NETCOREAPP + if (!NativeLibrary.TryGetExport(_hModule.DangerousGetHandle(), funcSymbol, out funcPtr)) + { // symbol not found + funcPtr = IntPtr.Zero; + } +#else + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + funcPtr = NativeMethods.Win32.GetProcAddress(_hModule, funcSymbol); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + funcPtr = NativeMethods.Linux.DLSym(_hModule, funcSymbol); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + funcPtr = NativeMethods.Mac.DLSym(_hModule, funcSymbol); + } + else + { + throw new PlatformNotSupportedException(); + } +#endif + return funcPtr; + } + + protected bool HasFuncSymbol(string funcSymbol) + { + return GetRawFuncPtr(funcSymbol) != IntPtr.Zero; + } #endregion #region (abstract) DefaultLibFileName @@ -361,6 +395,7 @@ protected T GetFuncPtr(string funcSymbol) where T : Delegate /// Custom object to be passed to . protected virtual void ParseLoadData(object data) { + } #endregion diff --git a/Joveler.DynLoader/LoadManagerBase.cs b/Joveler.DynLoader/LoadManagerBase.cs index 0107141..3c02c50 100644 --- a/Joveler.DynLoader/LoadManagerBase.cs +++ b/Joveler.DynLoader/LoadManagerBase.cs @@ -163,7 +163,7 @@ public void GlobalInit(string libPath) /// /// Create DynLoaderBase singleton instance in a thread-safe way. /// - /// Custom object to be passed to . + /// Custom object to be passed to . public void GlobalInit(object data) { GlobalInit(null, data); @@ -173,7 +173,7 @@ public void GlobalInit(object data) /// Create DynLoaderBase singleton instance in a thread-safe way. /// /// A native library file to load. - /// Custom object to be passed to . + /// Custom object to be passed to . public void GlobalInit(string libPath, object data) { lock (_loadLock) From d097eba3c2be78f5c01283bd9e172d41ff8f0b1a Mon Sep 17 00:00:00 2001 From: Hajin Jang Date: Tue, 8 Aug 2023 02:11:42 +0900 Subject: [PATCH 10/10] Prepare v2.2.0 release --- CHANGELOG.md | 31 +++++-- Joveler.DynLoader.Tests/SimpleZLib.cs | 5 +- Joveler.DynLoader.Tests/SimpleZLibTests.cs | 3 + Joveler.DynLoader/DynLoaderBase.cs | 50 ++++++----- Joveler.DynLoader/Joveler.DynLoader.csproj | 6 +- Joveler.DynLoader/LoadManagerBase.cs | 18 ++-- Joveler.DynLoader/NativeMethods.cs | 2 +- Joveler.DynLoader/PlatformConvention.cs | 2 +- Joveler.DynLoader/SafeLibHandle.cs | 2 +- README.md | 6 ++ USAGE.md | 99 +++++++++++++++++++++- 11 files changed, 178 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06ef9e3..e73f49a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,26 @@ ## v2.x +### v2.2.0 + +Released on 2023-08-08. + +- Allow passing a custom object when loading a native library. + - Add `LoadManagerBase.GlobalInit()` overloadings with custom object parameter. + - Add `DynLoaderBase.LoadLibrary()` overloadings with custom object parameter. + - Add virtual method `DynLoaderBase.HandleLoadData()`. + - Add helper method `DynLoaderBase.HasFuncSymbol()`. + +### v2.1.1 + +Released on 2022-02-15. + +- Official support for ARM64 macOS. +- Unify .NET Framework 4.5.1 codebase and .NET Standard 2.0 codebase. + ### v2.1.0 -Release in 2021.04.05. +Released on 2021-04-05. - Avoid calling virtual methods from constructors in `DynLoaderBase`. - Users must call `DynLoaderBase.LoadLibrary` after creating an instance. @@ -14,7 +31,7 @@ Release in 2021.04.05. ### v2.0.0 -Released in 2020.04.24. +Released on 2020-04-24. - Use `NativeLoader` on .NET Core 3.x build. - `DynLoaderBase` now throws [DllNotFoundException](https://docs.microsoft.com/en-US/dotnet/api/system.dllnotfoundexception) and [EntryPointNotFoundException](https://docs.microsoft.com/en-US/dotnet/api/system.entrypointnotfoundexception) instead of [ArgumentException](https://docs.microsoft.com/en-US/dotnet/api/system.argumentexception) and [InvalidOperationException](https://docs.microsoft.com/en-us/dotnet/api/system.invalidoperationexception). @@ -30,31 +47,31 @@ Released in 2020.04.24. ### v1.3.0 -Released in 2020.02.29. +Released on 2020-02-29. - Add `size_t` helper methods. - Rename AutoStringToCoTaskMem() into StringToCoTaskMemAuto(). ### v1.2.1 -Released in 2019.10.31. +Released on 2019-10-31. - Address `libdl.so` naming issue for CentOS ([#1](https://github.com/ied206/Joveler.DynLoader/issues/1)) ### v1.2.0 -Released in 2019.10.16. +Released on 2019-10-16. - Add platform convention helper properties and methods ### v1.1.0 -Released in 2019.10.15. +Released on 2019-10-15. - Add `LoadManagerBase` abstract class ### v1.0.0 -Released in 2019.10.15. +Released on 2019-10-15. - The initial release of the cross-platform native dynamic library loader for .NET. diff --git a/Joveler.DynLoader.Tests/SimpleZLib.cs b/Joveler.DynLoader.Tests/SimpleZLib.cs index 08720ee..86bc43c 100644 --- a/Joveler.DynLoader.Tests/SimpleZLib.cs +++ b/Joveler.DynLoader.Tests/SimpleZLib.cs @@ -40,6 +40,7 @@ protected override string DefaultLibFileName public bool HasUnknownSymbol { get; private set; } = true; public bool HasCrc32Symbol { get; private set; } = false; + public IntPtr UnknownRawPtr { get; private set; } = IntPtr.Zero; public IntPtr DeflateRawPtr { get; private set; } = IntPtr.Zero; #endregion @@ -48,8 +49,8 @@ protected override string DefaultLibFileName internal Cdecl _cdecl = new Cdecl(); #endregion - #region ParseCustomData - protected override void ParseLoadData(object data) + #region HandleCustomData + protected override void HandleLoadData(object data) { if (!(data is SimpleZLibLoadData loadData)) return; diff --git a/Joveler.DynLoader.Tests/SimpleZLibTests.cs b/Joveler.DynLoader.Tests/SimpleZLibTests.cs index c6473e4..be958fd 100644 --- a/Joveler.DynLoader.Tests/SimpleZLibTests.cs +++ b/Joveler.DynLoader.Tests/SimpleZLibTests.cs @@ -161,9 +161,12 @@ private void ManagerTemplate(string libPath, bool isWindowsStdcall) Assert.IsTrue(dupInitGuard); Console.WriteLine(manager.Lib.ZLibVersion()); + Console.WriteLine($"UnknownRawPtr = 0x{manager.Lib.UnknownRawPtr:X8}"); + Console.WriteLine($"DeflateRawPtr = 0x{manager.Lib.DeflateRawPtr:X8}"); Assert.IsFalse(manager.Lib.HasUnknownSymbol); Assert.IsTrue(manager.Lib.HasCrc32Symbol); + Assert.AreEqual(IntPtr.Zero, manager.Lib.UnknownRawPtr); Assert.AreNotEqual(IntPtr.Zero, manager.Lib.DeflateRawPtr); bool dupCleanGuard = false; diff --git a/Joveler.DynLoader/DynLoaderBase.cs b/Joveler.DynLoader/DynLoaderBase.cs index 726b914..b981c47 100644 --- a/Joveler.DynLoader/DynLoaderBase.cs +++ b/Joveler.DynLoader/DynLoaderBase.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License @@ -146,20 +146,20 @@ public void LoadLibrary(string libPath) } /// - /// Load a native dynamic library from a path of `DefaultLibFileName`. + /// Load a native dynamic library from a path of `DefaultLibFileName`, with custom object. /// - /// Custom object to be passed to . - public void LoadLibrary(object data) + /// Custom object has been passed to . + public void LoadLibrary(object loadData) { - LoadLibrary(null, data); + LoadLibrary(null, loadData); } /// - /// Load a native dynamic library from a given path. + /// Load a native dynamic library from a given path, with custom object. /// /// A native library file to load. - /// Custom object to be passed to . - public void LoadLibrary(string libPath, object data) + /// Custom object has been passed to . + public void LoadLibrary(string libPath, object loadData) { // Should DynLoaderBase use default library filename? if (libPath == null) @@ -172,7 +172,7 @@ public void LoadLibrary(string libPath, object data) LibPath = libPath; // Parse custom load data - ParseLoadData(data); + HandleLoadData(loadData); // Use .NET Core's NativeLibrary when available #if NETCOREAPP @@ -269,11 +269,11 @@ public void LoadLibrary(string libPath, object data) #region (protected) GetFuncPtr, GetRawFuncPtr, HasFuncSymbol /// - /// Get a delegate of a native function from a library. - /// The method will use name of the given delegate T as function symbol. + /// Get a delegate of a native function from the library. + /// The method will use name of the given delegate T as a function symbol. /// - /// Delegate type of a native function. - /// Delegate instance of a native function. + /// Delegate type of the native function. + /// Delegate instance of the native function. /// Throwen if the given function symbol was not found. protected T GetFuncPtr() where T : Delegate { @@ -282,11 +282,11 @@ protected T GetFuncPtr() where T : Delegate } /// - /// Get a delegate of a native function from a library. + /// Get a delegate of a native function from the library. /// - /// Delegate type of a native function. + /// Delegate type of the native function. /// Name of the exported function symbol. - /// Delegate instance of a native function. + /// Delegate instance of the native function. /// Throwen if the given function symbol was not found. protected T GetFuncPtr(string funcSymbol) where T : Delegate { @@ -342,6 +342,11 @@ protected T GetFuncPtr(string funcSymbol) where T : Delegate return Marshal.GetDelegateForFunctionPointer(funcPtr); } + /// + /// Get a raw pointer of a native function from the library. + /// + /// Name of the exported function symbol. + /// Raw pointer address of the native function. Returns IntPtr.Zero if the symbol was not found. protected IntPtr GetRawFuncPtr(string funcSymbol) { IntPtr funcPtr = IntPtr.Zero; @@ -371,6 +376,11 @@ protected IntPtr GetRawFuncPtr(string funcSymbol) return funcPtr; } + /// + /// Check if the library has a native function symbol. + /// + /// Name of the exported function symbol. + /// Returns true if the address of the exported symbol was found. protected bool HasFuncSymbol(string funcSymbol) { return GetRawFuncPtr(funcSymbol) != IntPtr.Zero; @@ -388,12 +398,12 @@ protected bool HasFuncSymbol(string funcSymbol) protected abstract string DefaultLibFileName { get; } #endregion - #region (virtual) ParseLoadData + #region (virtual) HandleLoadData /// - /// Parse custom object passed into . + /// Handle custom object passed into . /// - /// Custom object to be passed to . - protected virtual void ParseLoadData(object data) + /// Custom object has been passed to . + protected virtual void HandleLoadData(object data) { } diff --git a/Joveler.DynLoader/Joveler.DynLoader.csproj b/Joveler.DynLoader/Joveler.DynLoader.csproj index e962e12..37bc163 100644 --- a/Joveler.DynLoader/Joveler.DynLoader.csproj +++ b/Joveler.DynLoader/Joveler.DynLoader.csproj @@ -15,7 +15,11 @@ Supports Windows, Linux, and macOS. https://github.com/ied206/Joveler.DynLoader images\Logo.png https://github.com/ied206/Joveler.DynLoader - - Allow passing arbitrary objects to GlobalInit(). + - Allow passing a custom object when loading a native library. + - Add `LoadManagerBase.GlobalInit()` overloadings with custom object parameter. + - Add `DynLoaderBase.LoadLibrary()` overloadings with custom object parameter. + - Add virtual method `DynLoaderBase.HandleLoadData()`. + - Add helper method `DynLoaderBase.HasFuncSymbol()`. native pinvoke interop dynamic library loader dll so dylib diff --git a/Joveler.DynLoader/LoadManagerBase.cs b/Joveler.DynLoader/LoadManagerBase.cs index 3c02c50..b2440de 100644 --- a/Joveler.DynLoader/LoadManagerBase.cs +++ b/Joveler.DynLoader/LoadManagerBase.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License @@ -161,20 +161,20 @@ public void GlobalInit(string libPath) } /// - /// Create DynLoaderBase singleton instance in a thread-safe way. + /// Create DynLoaderBase singleton instance in a thread-safe way, with a custom object. /// - /// Custom object to be passed to . - public void GlobalInit(object data) + /// Custom object to be passed to . + public void GlobalInit(object loadData) { - GlobalInit(null, data); + GlobalInit(null, loadData); } /// - /// Create DynLoaderBase singleton instance in a thread-safe way. + /// Create DynLoaderBase singleton instance in a thread-safe way, with a custom object. /// /// A native library file to load. - /// Custom object to be passed to . - public void GlobalInit(string libPath, object data) + /// Custom object to be passed to . + public void GlobalInit(string libPath, object loadData) { lock (_loadLock) { @@ -183,7 +183,7 @@ public void GlobalInit(string libPath, object data) Lib = CreateLoader(); PreInitHook(); - Lib.LoadLibrary(libPath, data); + Lib.LoadLibrary(libPath, loadData); PostInitHook(); } } diff --git a/Joveler.DynLoader/NativeMethods.cs b/Joveler.DynLoader/NativeMethods.cs index f03ac53..9cfb867 100644 --- a/Joveler.DynLoader/NativeMethods.cs +++ b/Joveler.DynLoader/NativeMethods.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License diff --git a/Joveler.DynLoader/PlatformConvention.cs b/Joveler.DynLoader/PlatformConvention.cs index e43cef9..0a3ee10 100644 --- a/Joveler.DynLoader/PlatformConvention.cs +++ b/Joveler.DynLoader/PlatformConvention.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License diff --git a/Joveler.DynLoader/SafeLibHandle.cs b/Joveler.DynLoader/SafeLibHandle.cs index 96f6dd4..e6f822f 100644 --- a/Joveler.DynLoader/SafeLibHandle.cs +++ b/Joveler.DynLoader/SafeLibHandle.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2019-2021 Hajin Jang + Copyright (C) 2019-2023 Hajin Jang Licensed under MIT License. MIT License diff --git a/README.md b/README.md index f11da23..9bce709 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,12 @@ The library provides advanced p/invoke functionality of C functions using [Nativ | Linux | NativeLibrary, libdl | x64, armhf, arm64 | | macOS | NativeLibrary, libdl | x64, arm64 | +### Helps needed! + +- Android support and testing + - While I guess Android support on .NET Standard 2.0 target may be similar to Linux, I do not have any time to test on Android right now. + - On .NET/.NET Core, availibity of the `NativeLibrary` on Android has not been tested yet. + ## Usage See [USAGE.md](./USAGE.md). diff --git a/USAGE.md b/USAGE.md index 6bd2c79..9976e8d 100644 --- a/USAGE.md +++ b/USAGE.md @@ -48,7 +48,8 @@ Follow these steps to use a wrapper library. public static void GlobalCleanup() => Manager.GlobalCleanup(); } ``` -1. Call `GlobalInit()` to load native functions. +1. Call one of `GlobalInit` functions to load native functions. + - You may call `GlobalInit(object loadData)` or `GlobalInit(string libPath, object loadData)` instead to pass a custom object. It would be handled by `DynLoaderBase.HandleLoadData()` later. 1. Call delegate instances to call corresponding native functions. ## DynLoaderBase @@ -105,9 +106,37 @@ public SimpleFileMagic() : base() { } ### LoadLibrary +```csharp +/// +/// Load a native dynamic library from a path of `DefaultLibFileName`. +/// +public void LoadLibrary(); +/// +/// Load a native dynamic library from a given path. +/// +/// A native library file to load. +public void LoadLibrary(string libPath); +/// +/// Load a native dynamic library from a path of `DefaultLibFileName`, with custom object. +/// +/// Custom object has been passed to . +public void LoadLibrary(object loadData); +/// +/// Load a native dynamic library from a given path, with custom object. +/// +/// A native library file to load. +/// Custom object has been passed to . +public void LoadLibrary(string libPath, object loadData); +``` + After creating an instance of a derived class, make sure to call `LoadLibrary()` to load a native library. After that, you can invoke extern native functions via delegate instances. -`LoadLibrary(string libPath)` loads that specific native library. The parameterless version loads the default native library from the base system. +| Signature | Description | +|-----------------|-------------| +| `LoadLibrary()` | Loads the default native library from the base system. Works only if `DefaultLibFileName` is not null. | +| `LoadLibrary(string libPath)` | Loads specific native library from the path. | +| `LoadLibrary(object loadData)` | Pass a custom object, which would be handled by `HandleLoadData()`. Otherwise it is equal to `LoadLibrary()`. | +| `LoadLibrary(string libPath, object loadData)` | Pass a custom object, which would be handled by `HandleLoadData()`. Otherwise it is equal to `LoadLibrary(string libPath)`. | When it fails to find a native library, [DllNotFoundException](https://docs.microsoft.com/en-US/dotnet/api/system.dllnotfoundexception?view=netcore-3.1) is thrown. @@ -138,6 +167,11 @@ protected abstract void LoadFunctions(); /// Clear pointer of native functions. Called in Dispose(bool). /// protected abstract void ResetFunctions(); +/// +/// Handle custom object passed into . +/// +/// Custom object has been passed to . +protected virtual void HandleLoadData(object data) { } ``` #### LoadFunctions() @@ -167,9 +201,9 @@ protected override void LoadFunctions() #### ResetFunctions() -Override `ResetFunctions()` when you want to explicitly clear native resources and delegate assignments. +Always override `ResetFunctions()` with a code clearing native resources and delegate assignments. -Usually, the override of this method is not required, as the library handle is automatically cleared when the instance is disposed of. But if you need to clear delegate assignments manually, you have to implement them. +In most platforms, simply assigning `null` to function pointers is suffice. #### DefaultLibFileName @@ -193,6 +227,63 @@ protected override string DefaultLibFileName } ``` +#### HandleLoadData() + +Override `HandleLoadData()` to put a business logic to handle custom object which has been passed to `LoadManagerBase.GlobalInit()`. + +This functions is called after the `LibPath` property is set to native library path, and before `LoadFunctions()` is called. + +You are able to access the results of `HandleLoadData()` from `LoadFunctions()`. + +For example, you may need to override it to support both `cdecl` and `stdcall` ABIs of the same library. + +**Example** + +```csharp +public class SimpleZLibLoadData +{ + public bool IsWindowsStdcall { get; set; } = true; +} +``` + +```csharp +private bool _isWindowsStdcall = true; + +protected override void HandleLoadData(object data) +{ + if (!(data is SimpleZLibLoadData loadData)) + return; + + _isWindowsStdcall = loadData.IsWindowsStdcall; +} + +internal class Stdcall +{ + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public unsafe delegate uint adler32(uint adler, byte* buf, uint len); + public adler32 Adler32; +} + +internal class Cdecl +{ + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public unsafe delegate uint adler32(uint adler, byte* buf, uint len); + public adler32 Adler32; +} + +protected override void LoadFunctions() +{ + if (_isWindowsStdcall) + { + _stdcall.Adler32 = GetFuncPtr(nameof(Stdcall.adler32)); + } + else + { + _cdecl.Adler32 = GetFuncPtr(nameof(Cdecl.adler32)); + } +} +``` + ### Platform Conventions Native function signatures are changed by platform differences, such as OS and architecture. Sometimes you have to maintain two or more signature sets to accommodate this difference. To make your life easy, `DynLoaderBase` provides helper properties and methods.