如何通过mono从linux中的python代码调用.dll?

问题描述

我有一个带有 debian python3.6 基础映像的 docker 容器,我正在尝试在其上安装 Mono 以调用实用程序 .dll(使用 Visual Studio 编译的 .NET Framework 程序集(“发布”)选项)) 来自我的 python 代码。我安装了mono,因为我的python 代码需要使用pythonnet。当我尝试使用以下代码行进行调用时:

clr.AddReference(PATH_TO_DLL)

Mono 崩溃并显示以下堆栈跟踪:

mono_gdb_render_native_backtraces not supported on this platform,unable to find gdb or lldb

这是我的 Dockerfile 的样子:

FROM python:3.6

workdir /opt

# create a virtual environment and add it to PATH so that it is 
applied for all future RUN and CMD calls
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

# install msodbcsql17
RUN apt-get update \
    && apt-get install -y curl apt-transport-https gnupg2 \
    && curl https://packages.microsoft.com/keys/microsoft.asc | 
apt-key add - \
    && curl 
   https://packages.microsoft.com/config/debian/9/prod.list > 
/etc/apt/sources.list.d/mssql-release.list \
    && apt-get update \
    && ACCEPT_EULA=Y apt-get install -y msodbcsql17 mssql-tools


# Install Mono for pythonnet.
RUN apt-get update \
&& apt-get install --yes \
    dirmngr \
    clang \
    gnupg \
    ca-certificates \
    # Dependency for pyodbc.
    unixodbc-dev \
&& apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF \
&& echo "deb http://download.mono-project.com/repo/debian 
stretch/snapshots/5.20 main" | tee /etc/apt/sources.list.d/mono- 
   official-stable.list \
    && apt-get update \
    && apt-get install --yes \
    mono-devel=5.20\* \
    && rm -rf /var/lib/apt/lists/*

RUN python3 -m venv $VIRTUAL_ENV \
# From here on,use virtual env's python.
&& venv/bin/pip install --upgrade pip \
&& venv/bin/pip install --no-cache-dir --upgrade pip setuptools wheel \

&& venv/bin/pip install --no-cache-dir -r requirements.txt \
# Dependency for pythonnet.
&& venv/bin/pip install --no-cache-dir pycparser \
&& venv/bin/pip install -U  --no-cache-dir "pythonnet==2.5.1" \
"pythonnet==2.5.1"

我不知道是什么导致了这个问题。任何帮助将不胜感激。

解决方法

来自Python.Net Issue Tracker

// This requires LINQ.
List<Branch> br = new List<Branch>(); // You can replace 'new List<Branch>()' with 'new()' if you're using C# 9.0 or newer.
while (true)
{
    Console.WriteLine("Enter the ID,code,and name of the branch,seperated by commas,or enter an empty string to finish:");
    string line = Console.ReadLine();
    if (line == String.Empty)
        break;
    string[] entry = line.Split(',');
    entry[0] = entry[0].Trim();
    entry[1] = entry[1].Trim();
    entry[2] = entry[2].Trim();
    entry[1] = entry[1].ToUpper();
    if (entry.Length != 3)
        Console.WriteLine("Incorrect number of arguments.");
    else if (!Int32.TryParse(entry[0],out int id))
        Console.WriteLine("Invalid ID entered.");
    else if (entry[2] == String.Empty)
        Console.WriteLine("Name must not be blank.");
    else if (!(entry[1].StartsWith("SBI") && Int32.TryParse(entry[1].Remove(0,3),out int code) && code >= 100000 && code <= 999999))
        Console.WriteLine("Invalid code format.");
    else if ((from e in br
                where ((id == e.Id)
                    || (entry[1] == e.Code)
                    || (entry[2] == e.Name))
                select e).Count() > 0)
        Console.WriteLine("Duplicate ID,or name entered.");
    else
        br.Add(new Branch(id,entry[1],entry[2])); // Again,you can replace 'new Branch()' with 'new()' if you're using C# 9.0 or newer.
}
foreach (Branch b in br)
    Console.WriteLine(b.Name);
Console.WriteLine("Press any key to continue...");
Console.ReadKey();