在我们的项目中,我们在.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.dll
和SqlServerSpatial140.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*
高度赞赏任何帮助。