System erstellen

System erstellen

Ich erstelle derzeit eine OpenGL-Anwendung in Visual Studio 2015 und habe alle meine Dinge für GLFW, GLEW usw. erfolgreich verknüpft und integriert.

Wenn ich meine Anwendung jedoch ausführe, muss ich sie einschließen glew32.dll, kein Problem. Ich hole mir einfach die x64-DLL und füge sie dem Projektordner hinzu. Wenn ich mein Programm jetzt jedoch im 32-Bit-Modus ausführe, bricht es ab, und umgekehrt, wenn ich die 32-Bit-DLL in einem 64-Bit-Programm verwenden würde. Die einzige kostengünstige Lösung hierfür besteht darin, die architekturspezifischen DLLs in die Build-Ordner einzuschließen.

Gibt es eine Möglichkeit, die DLLs architekturspezifisch einzubinden, da ich mein resultierendes Programm etwa in der folgenden Form unterbringen möchte:

Programmverzeichnis

  • Spiel.exe
  • game_x64.exe
  • x64 (Ordner)
    • glew32.dll
  • x32 (Ordner)
    • glew32.dll

Wenn so etwas nicht möglich ist, bin ich mehr als zufrieden, wenn ich stattdessen ein glew32.dllund glew32_x64.dllin einem Ordner unterbringen könnte, aber dazu wird es wahrscheinlich nie kommen, da die Bibliothek nicht nach der neuen DLL sucht ...

Antwort1

Der Artikel überSuchreihenfolge für Dynamic-Link-Bibliothekenhat tatsächlich auch etwas darüber, wie man die Art und Weise ändern kann, wie eine Anwendung nach einer DLL sucht. Es verweist nämlich aufSetDllDirectoryUndLoadLibraryExund noch einige mehr.

Antwort2

Es gibt mehrere Möglichkeiten, das Problem zu lösen.

System erstellen

MSBuild verfügt über viele Funktionen, die nicht über die Visual Studio-Benutzeroberfläche gesteuert werden können. Sie können fast überall Variablen verwenden, manchmal auch Bedingungen.

Sie können bedingte Blöcke in Ihrer Datei deklarieren .vcxproj(die nur XML ist),so was:

<Choose>
  <When Condition="'$(Platform)' == 'Win32'">
    <ItemGroup>
      <Reference Include="SomeProject">
        <HintPath>..\Libraries\x86\SomeProject.dll</HintPath>
      </Reference>
    </ItemGroup>
  </When>
  <Otherwise>
    <ItemGroup>
      <Reference Include="SomeProject">
        <HintPath>..\Libraries\x64\SomeProject.dll</HintPath>
      </Reference>
    </ItemGroup>
  </Otherwise>
</Choose>

Es gibt andere Lösungen, wieDieses hier:

<Content Include="..\..\MyContentFiles\**\*.*">
  <Link>%(RecursiveDir)%(Filename)%(Extension)</Link>
  <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

Es löst Ihr Problem nicht direkt, bietet aber zusätzliche Einblicke in die Fähigkeiten von MSBuild.

Ich hatte einmal eine funktionierende Lösung für ein sehr ähnliches Problem (Referenzieren nativer Bibliotheken von .NET mit Debug-/Release-Builds), aber diese blieb bei meinem früheren Arbeitgeber.

Wenn Sie der Meinung sind, dass MSBuild zu eingeschränkt ist, können Sie jederzeit Postbuild-Aufgaben erstellen.

Diese Lösung kann auch Teil der unten erwähnten Dual-Architektur-Lösung mit separaten Verzeichnissen sein, da sie zu einer besseren Automatisierung des Build-Prozesses beiträgt.

DLL-Vorladen

Rufen Sie LoadLibraryoder LoadLibraryExauf und laden Sie die richtige DLL manuell. Dies ist nur möglich, wenn Sie die Kontrolle haben, bevor die DLL automatisch vom OS-Loader geladen wird.

Separate Verzeichnisse

Legen Sie einen Launcher in das oberste Verzeichnis. Legen Sie dann die x86- und x64-Builds in separate Verzeichnisse:

.\Launcher.exe
.\x64\Game.exe
.\x64\glew32.dll
.\x86\Game.exe
.\x86\glew32.dll

Suchpfad

Meiner Meinung nach sollte dies in einer vollständig kontrollierten Umgebung nie notwendig sein.

verwandte Informationen