无法加载共享库“ SqlServerSpatial140.dll”或其依赖项之一

时间:2019-01-31 06:17:01

标签: c# sql-server-2008 .net-core spatial

在我们的项目中,我们在.net核心应用程序中使用Microsoft.SqlServer.Types库,并遇到上述错误。 我知道该库与.net核心不兼容,但是对于基本地理数据处理而言,它可以正常工作,但是在某些尝试加载SqlServerSpatial140.dll库的情况下,我们会收到此错误。

在查看Microsoft.SqlServer.Types库的帮助文件时,我尝试创建一种为Linux平台动态加载SqlServerSpatial140.dll的方法。是的,我们在Linux内的docker容器中。

这是我尝试过的代码

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,因此对此方法的调用就像这样

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

我们从var error = Marshal.PtrToStringAnsi(dlerror());行得到的错误是invalid ELF header

我正在使用msvcr120.dllSqlServerSpatial140.dll的64位版本,并从.nuget\packages\microsoft.sqlserver.types\14.0.1016.290\nativeBinaries\x64文件夹中获取了这些库。

下面是nuget软件包随附的Loader.cs文件的稍作修改的版本

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*

高度赞赏任何帮助。

0 个答案:

没有答案