【问题标题】:MonoGame application says SDL.dll is missing, even though it's there. Why?MonoGame 应用程序说 SDL.dll 丢失,即使它在那里。为什么?
【发布时间】:2014-08-06 22:54:25
【问题描述】:

我有一个使用 Visual Studio 中的 Linux 游戏模板构建的 MonoGame 应用程序。它使用 .NET 或 Mono 在 Windows 上运行,但在 Linux 上失败。

错误是关于 SDL.dll 的 DllNotFoundException,但 SDL.dll 始终位于二进制文件的目录中。该文件不是 CLR 程序集,因此不在参考中。相反,我在构建期间从 MonoGame 的 Assemblies/Linux 目录复制了它(并且所有相关的 CLR 程序集也从该文件夹复制)。无论我是在 Visual Studio 或 Xamarin Studio 的 Windows 下还是在 MonoDevelop 的 Linux 下构建项目,都会出现错误。没有构建错误。

这是相关的堆栈跟踪:

System.DllNotFoundException: SDL.dll
  at (wrapper managed-to-native) Tao.Sdl.Sdl:__SDL_InitSubSystem (int)
  at Tao.Sdl.Sdl.SDL_InitSubSystem (Int32 flags) [0x00000] in <filename unknown>:0 
  at Microsoft.Xna.Framework.OpenTKGamePlatform..ctor (Microsoft.Xna.Framework.Game game) [0x00000] in <filename unknown>:0 
  at Microsoft.Xna.Framework.GamePlatform.Create (Microsoft.Xna.Framework.Game game) [0x00000] in <filename unknown>:0 
  at Microsoft.Xna.Framework.Game..ctor () [0x00000] in <filename unknown>:0 

(我没有包含代码,因为这与我的代码无关 - 即使我从模板构建一个新项目也会发生这种情况。我已经在谷歌上搜索了几个小时并尝试了所有组合各种论坛上的建议,但我还没有找到解决方案。)

我能做些什么来解决这个问题?


附录: 使用MONO_LOG_LEVEL=debug,我可以看到运行时尝试定位 DLL,但他们都说找不到该文件。当我尝试通过将文件重命名为libSDL.dll(或它正在寻找的任何其他内容)来“帮助”运行时时,它会显示“无效的 ELF 标头”并忽略它。这可能是意料之中的,因为它看起来像一个 Win32 二进制文件(不是 CLR 程序集)。

【问题讨论】:

  • 如果它不是一个 CLR 程序集(我同意,它可能不是),那么它就是一个 Windows 格式的 PE 可执行文件。 Linux 本身无法识别这一点,您需要配置 Wine 集成以让 Mono 加载它。即使这样,它也可能会或可能不会正确运行。也许你可以得到一个导出相同函数的 libSDL.so 文件?
  • @BenVoigt 我刚刚发现了问题所在,现在给出答案。

标签: c# sdl monogame


【解决方案1】:

上下文:

确实,SDL.dll(来自 Assemblies/Linux)是一个 Win32 二进制文件。它包含在“MonoGame for Linux”模板中的原因是游戏也可以在 Windows 下运行。在 Linux 下,DLL 是不用动的。相反,Mono 搜索 SDL 库的本机 Linux 版本。但是,由于某种原因,它无法映射。

解决方案:

  1. 确保您的 Linux 系统上安装了 libSDL 库。
  2. 转到您的项目并添加一个名为Tao.Sdl.dll.config 的文件。这是因为我们要为 Tao.Sdl.dll 程序集编写应用程序配置文件(因为对 SDL 的调用发生在 Tao.Sdl.dll 内部)。
  3. 确保此新文件的构建操作为 Content 并且已复制到输出目录。
  4. 在新文件中写入以下内容(适用于 libSDL 1.2 - 其他版本可能需要不同的名称):

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <dllmap dll="SDL.dll" target="libSDL-1.2.so.0" />
      <dllmap dll="SDL_image.dll" target="libSDL_image-1.2.so.0" />
      <dllmap dll="SDL_mixer.dll" target="libSDL_mixer-1.2.so.0" />
      <dllmap dll="SDL_ttf.dll" target="libSDL_ttf-2.0.so.0" />
      <dllmap dll="SDL_net.dll" target="libSDL_net-1.2.so.0" />
      <dllmap dll="smpeg.dll" target="libsmpeg-0.4.so.0" />
      <dllmap dll="SDL_gfx.dll" target="libSDL_gfx.so.4" />
    </configuration>
    
  5. 清理并构建。

现在 Mono 应该有足够的信息在您的系统上找到 libSDL。

【讨论】:

    【解决方案2】:

    确实,您找到的解决方案可以解决您面临的问题,但是现在有一种更简单的方法。

    1. 在您的项目中安装 Linux Nuget (https://www.nuget.org/profiles/MonoGame)。这将自动生成必要的映射。
    2. (可能没有必要)如果您从 Linux 模板启动项目,新的 Nugets 应该已经删除了默认添加的所有引用,但如果没有,请按照 Nuget 自述文件中的说明删除这些引用
    3. 在 Linux 操作系统中运行时,您可能需要安装一些可能依赖于您的系统的 SDL 相关库。例如,在我的情况下(debian),我已经拥有 libsdl1.2debian(提供“libSDL-1.2.so.0”),但是当我开始游戏时,它发现“libSDL_mixer-1.2.so.0”缺失,因此我在 aptcache 搜索中查找并找到了 libsdl-mixer1.2 包。安装后游戏运行没有问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 2018-12-27
      • 1970-01-01
      相关资源
      最近更新 更多