В нашем проекте мы используем библиотеку 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*
Любая помощь высоко ценится.