csharp/Functions.Dll/FunctionsImport.cs (64 lines of code) (raw):

using System; using System.Runtime.InteropServices; using EPAM.Deltix.Utilities; namespace Functions { static class Const { // Debug logging flag internal static bool Verbose = false; } internal interface FunctionsInterface { double TestFunction(double a, double b); } internal class FunctionsInterfaceImpl : FunctionsInterface { static FunctionsInterfaceImpl() { Load(); } public static void Load() { // Also possible to just move ResourceLoader call into this constructor if (Const.Verbose) Console.WriteLine("Native Init..."); if (isLoaded) return; lock (isLoadedLock) { if (isLoaded) return; if (Const.Verbose) Console.WriteLine("Will load native lib"); var varMapper = new VariablesMapper(typeof(FunctionsInterfaceImpl)); var unpackEnvVarName = varMapper.PackageLast.ToUpperInvariant() + "_UNPACK_ROOT"; var unpackPath = Environment.GetEnvironmentVariable(unpackEnvVarName); Console.WriteLine($"Check {unpackEnvVarName} environment variable: {unpackPath ?? "null"}"); if (unpackPath == null) unpackPath = "$(TEMP)/$(PACKAGE)/$(VERSION)/$(ARCH)"; var rl = ResourceLoader.From(typeof(FunctionsInterfaceImpl), $"Functions.{varMapper.Os}.{varMapper.Arch}.*") .To(varMapper.Substitute(unpackPath)) .Load(); //.To("c:/Users/ChuprinB/Dropbox/Projects/decimal.net/NativeUtils/csharp/Functions/DotNet/$(VERSION)/$(ARCH)").Load(); //.To("Functions/DotNet/Debug").Load(); // If we don't want automatic target root path selection and fallback path features: //.To("$(TEMP)/Functions/DotNet/$(VERSION)/$(ARCH)")/*.RetryTimeout(2000)*/.Load(); //.To("$(TEMP)/_/$(RANDOM)").Load(); //.To("$(TEMP)/_/$(VERSION)/$(ARCH)").AlwaysOverwite(true).ReusePartiallyDeployed(false).TryRandomFallbackSubDirectory(true).Load(); if (Const.Verbose) Console.WriteLine("Loaded native lib at: {0}", rl.ActualDeploymentPath); isLoaded = true; } } public double TestFunction(double a, double b) => FunctionsImport.TestFunction(a, b); internal static bool isLoaded = false; internal static object isLoadedLock = new object(); } internal class FunctionsImport { internal const string NativeDllName = "FunctionsNative" + Version.versionDashed; static FunctionsImport() { FunctionsInterfaceImpl.Load(); // Assume we need to call a native initialization function once var rv = TestFunction(0, 0); if (Const.Verbose) Console.WriteLine($"Some init method returned: {rv}"); } [DllImport(NativeDllName, EntryPoint="testFunction", CallingConvention = CallingConvention.StdCall)] internal static extern double TestFunction(double a, double b); } }