Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#111 #112

Merged
merged 2 commits into from
Nov 29, 2020
Merged

#111 #112

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).

68 changes: 30 additions & 38 deletions src/libplctag.NativeImport/LibraryExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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<string, string> GetResourceName()
static LibraryInfo GetAppropriateLibrary()
{

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && RuntimeInformation.ProcessArchitecture == Architecture.X86)
{
return new Tuple<string, string>("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<string, string>("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<string, string>("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<string, string>("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<string, string>("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");
}

}
Expand All @@ -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;
}
}

}
}