diff --git a/README.md b/README.md index 3def7af1..6fc5e094 100644 --- a/README.md +++ b/README.md @@ -24,12 +24,14 @@ For usage, see the examples in the example projects: libplctag.NativeImport provides low-level (raw) access to the native libplctag library. The purpose of this package is to expose the native library API (which is written in C), and handle platform and configuration issues. -Documentation for the native API can be found [here](https://github.com/libplctag/libplctag/wiki/API). +Documentation for the native API can be found [here](https://github.com/libplctag/libplctag/wiki/API). An example of its usage can be found [here](https://github.com/libplctag/libplctag.NET/blob/master/src/Examples/CSharp%20DotNetCore/NativeImportExample.cs). -If you do wish to make use of the native library API in a .NET project, an example of it's usage can be found [here](https://github.com/libplctag/libplctag.NET/blob/master/src/Examples/CSharp%20DotNetCore/NativeImportExample.cs). +During initialization, this package extracts to disk the appropriate native runtime. By default, it will overwrite any runtime that is already on disk. If you wish to disable this behaviour and use a different runtime (e.g. one that you've compiled yourself, or a pre-release), you can disable the Force Extract feature. -During initialization, this package extracts to disk the appropriate native runtime. By default, it will overwrite any runtime that is already on disk. If you wish to disable this behaviour and use a different runtime (e.g. one that you've manually compiled, or a pre-release), you can disable the Force Extract feature. ```csharp // Before any calls to any libplctag methods plctag.ForceExtractLibrary = false; ``` + +The libplctag native runtime can be compiled for [many platforms](https://github.com/libplctag/libplctag#platform-support), and not all supported platforms are shipped with this wrapper. If you get a `TypeLoadException`, chances are that you can still use this wrapper but you will need to [supply the runtime yourself](https://github.com/libplctag/libplctag/blob/master/BUILD.md). + diff --git a/src/libplctag.NativeImport/LibraryExtractor.cs b/src/libplctag.NativeImport/LibraryExtractor.cs index 188eea56..39403341 100644 --- a/src/libplctag.NativeImport/LibraryExtractor.cs +++ b/src/libplctag.NativeImport/LibraryExtractor.cs @@ -20,7 +20,13 @@ public static void Init(bool forceExtract = false) } - public static string GetExecutingAssemblyDirectory() + static bool LibraryExists(string folder) + { + var library = GetAppropriateLibrary(); + return File.Exists(Path.Combine(folder, library.FileName)); + } + + static string GetExecutingAssemblyDirectory() { string codeBase = Assembly.GetExecutingAssembly().CodeBase; UriBuilder uri = new UriBuilder(codeBase); @@ -30,65 +36,39 @@ public static string GetExecutingAssemblyDirectory() static void ExtractAppropriateLibrary(string folder) { - var embeddedResourceName = GetResourceName(); - var embeddedResourceFileName = embeddedResourceName.Item2; - - var embeddedResource = GetEmbeddedResource(embeddedResourceName.Item1 + "." + embeddedResourceName.Item2); - var newFileName = Path.Combine(folder, embeddedResourceFileName); - - if (embeddedResource == null) - throw new TypeLoadException("Could not could not find appropriate unmanaged library"); - - File.WriteAllBytes(newFileName, embeddedResource); - } - - public static bool LibraryExists(string folder) - { + var library = GetAppropriateLibrary(); + var embeddedResource = GetEmbeddedResource(library.ResourceName); + var extractPath = Path.Combine(folder, library.FileName); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return File.Exists(Path.Combine(folder, "plctag.dll")); - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return File.Exists(Path.Combine(folder, "libplctag.so")); - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - return File.Exists(Path.Combine(folder, "libplctag.dylib")); - } - else - { - throw new TypeLoadException("Platform not supported"); - } + File.WriteAllBytes(extractPath, embeddedResource); } - static Tuple GetResourceName() + static LibraryInfo GetAppropriateLibrary() { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.ProcessArchitecture == Architecture.X86) { - return new Tuple("libplctag.NativeImport.runtime.win_x86", "plctag.dll"); + return new LibraryInfo("libplctag.NativeImport.runtime.win_x86", "plctag.dll"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { - return new Tuple("libplctag.NativeImport.runtime.win_x64", "plctag.dll"); + return new LibraryInfo("libplctag.NativeImport.runtime.win_x64", "plctag.dll"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X86) { - return new Tuple("libplctag.NativeImport.runtime.linux_86", "libplctag.so"); + return new LibraryInfo("libplctag.NativeImport.runtime.linux_86", "libplctag.so"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { - return new Tuple("libplctag.NativeImport.runtime.linux_x64", "libplctag.so"); + return new LibraryInfo("libplctag.NativeImport.runtime.linux_x64", "libplctag.so"); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && RuntimeInformation.ProcessArchitecture == Architecture.X64) { - return new Tuple("libplctag.NativeImport.runtime.osx_x64", "libplctag.dylib"); + return new LibraryInfo("libplctag.NativeImport.runtime.osx_x64", "libplctag.dylib"); } else { - throw new TypeLoadException("This platform is not supported, could not load appropriate unmanaged library"); + throw new TypeLoadException("Could not could not find the appropriate unmanaged library"); } } @@ -105,5 +85,17 @@ static byte[] GetEmbeddedResource(string resourceName) } } + class LibraryInfo + { + public string ResourceName { get; set; } + public string FileName { get; set; } + + public LibraryInfo(string resourceNameWithoutFileName, string fileName) + { + ResourceName = $"{resourceNameWithoutFileName}.{fileName}"; + FileName = fileName; + } + } + } }