Что может привести к тому, что двоичный файл .NET Core загрузит собственную библиотеку, а затем вызовет исключение DllNotFoundException? - PullRequest
0 голосов
/ 12 января 2019

Я пытаюсь запустить игру SFML.NET на MacOS, портировав игру на .NET Core.

Мне не удалось заставить SFML правильно загрузить свои собственные зависимости во время выполнения, поэтому я настроил минимальный тестовый пример, чтобы попытаться изолировать проблему, и все еще получаю следующее сообщение об ошибке (я установил DYLD_PRINT_LIBRARIES):

dyld: loaded: /System/Library/Frameworks/CoreData.framework/Versions/A/CoreData
dyld: loaded: /System/Library/Frameworks/ServiceManagement.framework/Versions/A/ServiceManagement
dyld: loaded: /System/Library/PrivateFrameworks/BackgroundTaskManagement.framework/Versions/A/BackgroundTaskManagement
dyld: loaded: /usr/lib/libxslt.1.dylib
dyld: loaded: /usr/local/share/dotnet/shared/Microsoft.NETCore.App/2.2.0/libclrjit.dylib
dyld: loaded: /usr/local/share/dotnet/shared/Microsoft.NETCore.App/2.2.0/System.Globalization.Native.dylib
dyld: loaded: /usr/local/share/dotnet/shared/Microsoft.NETCore.App/2.2.0/System.Native.dylib
Hello World!
dyld: loaded: /Users/ashley/RiderProjects/SFML.NET Test/SFML.NET Test/bin/Debug/netcoreapp2.2/libcsfml-window.dylib
dyld: unloaded: /Users/ashley/RiderProjects/SFML.NET Test/SFML.NET Test/bin/Debug/netcoreapp2.2/libcsfml-window.dylib
dyld: loaded: libcsfml-window.dylib
dyld: unloaded: libcsfml-window.dylib

Unhandled Exception: System.DllNotFoundException: Unable to load shared library 'libcsfml-window.dylib' or one of its dependencies. In order to help diagnose loading problems, consider setting the DYLD_PRINT_LIBRARIES environment variable: dlopen(liblibcsfml-window.dylib.dylib, 1): image not found
   at SFML.Window.VideoMode.sfVideoMode_getDesktopMode()
   at SFML.Window.VideoMode.get_DesktopMode() in /Users/ashley/SFML.Net/src/Window/VideoMode.cs:line 86
   at SFML.NET_Test.Program.Main(String[] args) in /Users/ashley/RiderProjects/SFML.NET Test/SFML.NET Test/Program.cs:line 12
dyld: unloaded: /usr/local/share/dotnet/shared/Microsoft.NETCore.App/2.2.0/libhostpolicy.dylib

Код, который я пытаюсь запустить, выглядит следующим образом:

using System;
using SFML.Graphics;
using SFML.Window;

namespace SFML.NET_Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            RenderWindow window = new RenderWindow(VideoMode.DesktopMode, "Test");
            while (true)
            {
            }
        }
    }
}

У меня есть копии соответствующих нативных библиотек в рабочем каталоге и исполняемом бункере (это не постоянная установка - только во время эксперимента), и он пытается загрузить обе последовательности, прежде чем отказаться от разгрузить их.

Учитывая это, мне в основном интересно, что может привести к этому случаю?

Я подозреваю, что это может указывать на то, что моя библиотека неверной версии? (Я пробовал CSFML 2.2, 2.3, 2.5, так что ради здравого смысла я надеюсь, что это не так) Или, может быть, отсутствуют отсутствующие зависимости, которые он пытается и не может загрузить? Есть ли способ получить дополнительную информацию отладки из dyld?

Я пытался искать по этому поводу, но довольно сложно найти какие-либо полезные ресурсы, поэтому я был бы признателен за ссылки от людей, которые лучше понимают систему компоновки во время выполнения.

Я не совсем уверен, какая дополнительная информация будет полезна для ответа на этот вопрос. Я надеюсь, что есть определенный, четко определенный набор сценариев, в которых это поведение может проявиться, и которое я могу применить, чтобы решить мою конкретную проблему. В противном случае, я очень рад предоставить любую дополнительную информацию, которая поможет.

Моя .NET Core версия 2.2.101

1 Ответ

0 голосов
/ 18 января 2019

После обсуждения в комментариях кажется, что предварительно созданные двоичные файлы для SMFL имеют неверные пути и имена файлов, установленные внутри них. Такие проблемы обычно могут быть решены утилитами otool и install name tool для проверки двоичных файлов и последующего изменения путей / имен библиотек, которые необходимо загрузить.

Пример с otool -l может выглядеть так:

$ otool -l /path/to/binary
Load command 2 <-- OLD
          cmd LC_ID_DYLIB
      cmdsize 40
         name libtest.dylib (offset 24)
   time stamp 1 Wed Dec 31 18:00:01 1969

Чтобы изменить путь, который вы можете сделать:

$ install_name_tool -id "@loader_path/../libtest.dylib" libtest.dylib 

, который даст вам новый путь, такой как:

Load command 2 <-- NEW
          cmd LC_ID_DYLIB
      cmdsize 64
         name @loader_path/../libtest.dylib (offset 24)

Если вы хотите использовать rpath, вместо этого вы можете сделать:

$ install_name_tool -id "@rpath/libtest.dylib" libtest.dylib

Я ответил a previous question относительно rpath и loader_path, что более подробно описывает предмет. Каждый сценарий потенциально отличается в случае загрузки динамических библиотек, поэтому он действительно сводится к тому, что вы узнаете, исследуя через otool -l.

...