Не удается загрузить общую библиотеку 'SqlServerSpatial140.dll' или одну из ее зависимостей - PullRequest
0 голосов
/ 31 января 2019

В нашем проекте мы используем библиотеку Microsoft.SqlServer.Types в основном приложении .net и получаем вышеупомянутую ошибку.Я понимаю, что эта библиотека не совместима с ядром .net, но для базовой обработки географических данных это работает нормально, но для некоторых сценариев, когда она пытается загрузить библиотеку SqlServerSpatial140.dll, мы получаем эту ошибку.

Lookingв файле справки библиотеки Microsoft.SqlServer.Types я попытался создать метод динамической загрузки SqlServerSpatial140.dll для платформы Linux.Да, мы находимся в Docker-контейнере в Linux.

Это код, который я пробовал

public class LoadAssembly 
{
    [DllImport(@"/lib/x86_64-linux-gnu/libdl-2.24.so")]
    static extern IntPtr dlopen(String fileName, int flags);

    [DllImport(@"/lib/x86_64-linux-gnu/libdl-2.24.so")]
    static extern IntPtr dlerror();

    public static IntPtr LoadPosixLibrary(string libName)
    {
        const int RTLD_NOW = 2;
        if(File.Exists(libName))
        {
            var addr = dlopen(libName, RTLD_NOW);
            if(addr == IntPtr.Zero)
            {
                var error = Marshal.PtrToStringAnsi(dlerror());
                Logger.Log.Info($"Assembly not loaded {libName}. Error is {error}");

            }
            else
            {
                Logger.Log.Info($"Assembly loaded {libName}");
            }

            return addr;
        }
        else
        {
            Logger.Log.Info($"Assembly NOT FOUND {libName}");
            return IntPtr.Zero;
        }
    }

}

Вызов LoadPosixLibrary, где мы получили ошибку, поэтому вызов этого метода похож наthis

LoadAssembly.LoadPosixLibrary(@"/var/log/SqlServerTypes/x64/msvcr120.dll");                            
LoadAssembly.LoadPosixLibrary(@"/var/log/SqlServerTypes/x64/SqlServerSpatial140.dll");

И ошибка, которую мы получили из этой строки var error = Marshal.PtrToStringAnsi(dlerror());: invalid ELF header

Я использую 64-битные версии msvcr120.dll и SqlServerSpatial140.dll и взял эти библиотеки изПапка .nuget\packages\microsoft.sqlserver.types\14.0.1016.290\nativeBinaries\x64.

Ниже приведена слегка измененная версия файла Loader.cs, поставляемого с пакетом nuget

public class Utilities
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr LoadLibrary(string libname);

    /// <summary>
    /// Loads the required native assemblies for the current architecture (x86 or x64)
    /// </summary>
    /// <param name="rootApplicationPath">
    /// Root path of the current application. Use Server.MapPath(".") for ASP.NET applications
    /// and AppDomain.CurrentDomain.BaseDirectory for desktop applications.
    /// </param>
    public static void LoadNativeAssemblies(string rootApplicationPath)
    {
        var nativeBinaryPath = IntPtr.Size > 4
            ? Path.Combine(rootApplicationPath, @"SqlServerTypes/x64/")
            : Path.Combine(rootApplicationPath, @"SqlServerTypes/x86/");
        Directed.Telematics.Common.Utilities.Logger.Log.Info($"Native path is {nativeBinaryPath}");
        LoadNativeAssembly(nativeBinaryPath, "msvcr120.dll");
        LoadNativeAssembly(nativeBinaryPath, "SqlServerSpatial140.dll");
    }

    private static void LoadNativeAssembly(string nativeBinaryPath, string assemblyName)
    {

       var path = Path.Combine(nativeBinaryPath, assemblyName);
        var ptr = LoadLibrary(path);
        if (ptr == IntPtr.Zero)
        {
            throw new Exception(string.Format(
                "Error loading {0} (ErrorCode: {1})",
                assemblyName,
                Marshal.GetLastWin32Error()));
        }
    }
}

С этим кодом я получил следующую ошибку

*Unable to load shared library kernel32.dll or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable*

Любая помощь высоко ценится.

...