【问题标题】:System.DllNotFoundException: Unable to load shared library 'oqs' or one of its dependencies. in DockerSystem.DllNotFoundException:无法加载共享库 \'oqs\' 或其依赖项之一。在码头工人
【发布时间】:2023-02-16 11:09:19
【问题描述】:

我正在尝试在 docker 中运行一个 asp.net mvc 应用程序。我有一个已编译的 c 二进制文件,它在我的根项目目录中引用:liboqs.dylib、liboqs.so 和 oqs.dll。这是一个编译的 c 版本,但我有文件的 mac、linux 和 windows 版本,因此代码可以获取它需要的任何一个。代码像这样引用文件:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
private struct OQS_SIG
{
    public IntPtr method_name;
    public IntPtr alg_version;
    public byte claimed_nist_level;
    public byte euf_cma;
    public UIntPtr length_public_key;
    public UIntPtr length_secret_key;
    public UIntPtr length_signature;
    private IntPtr keypair_function; // unused
    private IntPtr sign_function; // unused
    private IntPtr verify_function; // unused
}

#region OQS native DLL functions
[DllImport("liboqs.so", CallingConvention = CallingConvention.Cdecl)]
extern private static IntPtr OQS_SIG_new(string method_name);

[DllImport("liboqs.so", CallingConvention = CallingConvention.Cdecl)]
extern private static int OQS_SIG_keypair(IntPtr sig, byte[] public_key, byte[] secret_key);

[DllImport("liboqs.so", CallingConvention = CallingConvention.Cdecl)]
extern private static int OQS_SIG_sign(IntPtr sig, byte[] signature, ref UIntPtr sig_len, byte[] message, int message_len, byte[] secret_key);

[DllImport("liboqs.so", CallingConvention = CallingConvention.Cdecl)]
extern private static int OQS_SIG_verify(IntPtr sig, byte[] message, int message_len, byte[] signature, int signature_len, byte[] public_key);

[DllImport("liboqs.so", CallingConvention = CallingConvention.Cdecl)]
extern private static void OQS_SIG_free(IntPtr sig);

[DllImport("liboqs.so", CallingConvention = CallingConvention.Cdecl)]
extern private static IntPtr OQS_SIG_alg_identifier(int index);

[DllImport("liboqs.so", CallingConvention = CallingConvention.Cdecl)]
extern private static int OQS_SIG_alg_count();

[DllImport("liboqs.so", CallingConvention = CallingConvention.Cdecl)]
extern private static int OQS_SIG_alg_is_enabled(string method_name);
#endregion

/// <summary>
/// List of supported mechanisms. Some mechanisms might have been disabled at runtime,
/// see <see cref="EnableddMechanisms"/> for the list of enabled mechanisms.
/// </summary>
public static ImmutableList<string> SupportedMechanisms { get; private set; }

/// <summary>
/// List of enabled mechanisms.
/// </summary>
public static ImmutableList<string> EnabledMechanisms { get; protected set; }

/// <summary>
/// Static constructor.
/// </summary>
static Sig()
{
    // initialize list of supported/enabled mechanisms
    List<string> enabled = new List<string>();
    List<string> supported = new List<string>();
    int count = OQS_SIG_alg_count();
    for (int i = 0; i < count; i++)
    {
        string alg = Marshal.PtrToStringAnsi(OQS_SIG_alg_identifier(i));
        supported.Add(alg);
        // determine if the alg is enabled
        if (OQS_SIG_alg_is_enabled(alg) == 1)
        {
            enabled.Add(alg);
        }
    }
    EnabledMechanisms = enabled.ToImmutableList<string>();
    SupportedMechanisms = supported.ToImmutableList<string>();
}

问题是当访问此二进制文件的代码运行时出现此错误:

System.DllNotFoundException: Unable to load shared library 'oqs' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liboqs: cannot open shared object file: No such file or directory

这是我的泊坞窗文件

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app

# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
RUN dotnet publish -c Release -o out
COPY liboqs* oqs ./out/

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "amaranth.dll"]

请注意,我正在将 liboqs 文件复制到正在构建应用程序的目录中。我什至进入我的 docker 容器的终端,发现所有 3 个 liboqs 文件都在 app 目录中。

值得一提的是,只要 liboqs 文件与主要可执行文件位于同一目录中,该应用程序就可以在没有 docker 的情况下完美运行。

那么问题是什么?如何让应用程序找到 liboqs 文件?

【问题讨论】:

  • 如果没有 .so 扩展名,它可以工作吗? .NET 通常会自动识别相应的文件扩展名。您也可以尝试通过 ssh 进入您的容器并检查该文件中是否有未解析的符号。 ldd -r -d liboqs.so
  • 我在没有 .so 的情况下尝试过。它仍然失败。我还没有尝试 ldd -r -d liboqs.so 命令

标签: c# c asp.net docker dllimport


【解决方案1】:

我在使用 DLLImport 和外部 Fortran 库时遇到了同样的问题。 Robin Lindner 建议的 ldd MyLibrary.so 命令突出显示了一些缺失的依赖项。我需要包含 -static-intel 参数来解决编译时缺少的依赖项:

./ifort -shared -fpic -static-intel -o MyLibrary.so MyLibrary.f90

c 二进制文件可能存在类似的问题。

【讨论】:

    猜你喜欢
    • 2019-12-02
    • 2022-10-24
    • 1970-01-01
    • 1970-01-01
    • 2020-07-11
    • 2012-09-15
    • 2018-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多