C# MonoGame应用程序表示SDL.dll丢失,尽管它';在那里。为什么?

C# MonoGame应用程序表示SDL.dll丢失,尽管它';在那里。为什么?,c#,sdl,monogame,C#,Sdl,Monogame,我在VisualStudio中使用Linux游戏模板构建了一个单游戏应用程序。它使用.NET或Mono在Windows上运行,但在Linux上失败 错误是关于SDL.dll的DllNotFoundException,但SDL.dll始终位于二进制文件的目录中。该文件不是CLR程序集,因此不在引用中。相反,我在构建过程中从MonoGame的Assemblies/Linux目录复制了它(所有相关的CLR程序集也从该文件夹复制)。无论我是在Visual Studio或Xamarin Studio中的W

我在VisualStudio中使用Linux游戏模板构建了一个单游戏应用程序。它使用.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 
System.DllNotFoundException:SDL.dll
at(包装器管理为本机)Tao.Sdl.Sdl:u Sdl_InitSubSystem(int)
在:0中的Tao.Sdl.Sdl.Sdl_InitSubSystem(Int32标志)[0x00000]处
在Microsoft.Xna.Framework.OpenTKGamePlatform..ctor(Microsoft.Xna.Framework.Game游戏)[0x00000]中:0
在Microsoft.Xna.Framework.GamePlatform.Create(Microsoft.Xna.Framework.Game Game)[0x00000]中:0
在Microsoft.Xna.Framework.Game..ctor()[0x00000]中:0
(我没有包含代码,因为这与我的代码无关——即使我从模板中构建了一个新项目,这种情况也会发生。我已经在谷歌上搜索了几个小时,并尝试了各种论坛上建议的所有组合,但我还没有找到解决方案。)

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



附录:通过
MONO\u LOG\u LEVEL=debug
,我可以看到运行时试图定位DLL,他们都说找不到该文件。当我试图通过将文件重命名为
libSDL.dll
(或它要查找的任何其他文件)来“帮助”运行时时,它会显示“无效ELF头”,并忽略它。这可能是意料之中的,因为它看起来像Win32二进制文件(不是CLR程序集)。

上下文:

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

解决方案:

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

    
    
  • 清洁和建造


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

    事实上,您找到的解决方案解决了您面临的问题,但是现在有一种更简单的方法

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

  • 如果它不是CLR程序集(我同意,它可能不是),那么它就是Windows格式的PE可执行文件。Linux本机没有意识到这一点,您需要配置Wine集成,以便Mono加载它。即使如此,它也可能运行正常,也可能运行不正常。也许你可以得到一个libSDL.so文件来导出相同的函数?@BenVoigt我刚刚发现了问题所在,现在正在回答。
    <?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>