Hallo,
nach vielen Stunden des Rumprobierens habe ich es tatsächlich geschafft, Assimp für mein .NET-4.0-Projekt zum Laufen zu bringen. Die Lösung ist etwas exotisch und vielleicht sind auch nicht alle der getanen Schritte notwendig, aber da es jetzt einmal bei mir läuft, möchte ich nichts mehr ändern. Für jeden, der irgendwann mal über die Suche den Thread findet und das selbst mal probieren will:
- Vom SVN-Repository Revision 1059 runterladen (ist der letzte Commit, der bei mit Out-of-the-box kompilierbar ist).
- Im Assimp-Verzeichnis nach port/Assimp.NET navigieren und Assimp.NET.sln mit Visual Studio 2008 (!) öffnen. Wenn man die Projektmappe mit VS2010 öffnet, wird sie automatisch konvertiert und die im ersten Post genannten Fehler treten auf.
- Die beiden C++-Projekte "assimp" und "Assimp_NET" in der Konfiguration "Release" für die Plattform "Win32" kompilieren, die resultierende Assimp.dll irgendwo zwischenspeichern für später.
- Alle *.cs-Dateien (und nur die) aus dem Verzeichnis port/Assimp.NET/Assimp.NET_CS in das Projekt kopieren, in dem man Assimp verwenden möchte. Ich habe dazu einen Unterordner AssimpNET in meiner Projektmappe angelegt. Das ist vermutlich ein Schritt, den man auch weglassen und weiter mit der Assimp.Interop.dll arbeiten könnte. Bei mir hat sich das ohne das zusätzliche Klassenbibliothek-Projekt entwickelt, weil ich viel im Code debuggt habe und das so angenehmer war.
- Die kopierten Dateien in VS2010 über "Hinzufügen | Vorhandenes Element..." zum Projekt hinzufügen.
- In dem Projekt, zu dem man die Dateien hinzugefügt hat, die oben erzeugte Assimp.dll hinzufügen. Damit die Datei nicht verloren geht, habe ich sie bei mir in das gleiche Verzeichnis kopiert wie die *.cs-Dateien.
- Eine der kopierten Dateien heißt "AssimpPINVOKE.cs". In der Datei finden sich viele Aufrufe nach dem Muster
Code: Alles auswählen
[DllImport("Assimp", EntryPoint = "SWIGRegisterExceptionCallbacks_Assimp")]
public static extern void SWIGRegisterExceptionCallbacks_Assimp(...)
Skurrilerweise wurde die Bibliothek Assimp.dll so nicht bei mir gefunden. Deshalb habe ich eine konstante mit dem Dateinamen angelegt und alle Verweise auf "Assimp" durch die Konstante ersetzt, also:
Code: Alles auswählen
public const string LibraryPath = "Assimp.dll";
[DllImport(AssimpPINVOKE.LibraryPath, EntryPoint = "SWIGRegisterExceptionCallbacks_Assimp")]
public static extern void SWIGRegisterExceptionCallbacks_Assimp(...)
So funktioniert es bei mir. Warum der letzte Schritt nötig ist, ist mir ein Rätsel.
Um noch auf die TypeInitializationException zu sprechen zu kommen, die mir wirklich sehr oft begegnet ist: Die Exception tritt immer auf, wenn ein statischer Member oder ein statischer Konstruktor eine Exception wirft - in diesemFall in der Klasse AssimpPINVOKE. Wer Probleme mit dem Einbinden hat, sollte sich die Zeile
Code: Alles auswählen
static SWIGExceptionHelper swigExceptionHelper = new SWIGExceptionHelper();
in Datei AssimpPINVOKE.cs ansehen. Direkt darüber steht in der Inline-Definition der Klasse auch der Konstruktor für SWIGExceptionHelper, der scheitern wird, wenn es ein Problem mit der Bibliothek gibt. Deshalb habe ich den Konstruktor mit einem Try-Catch-Block und einem Breakpoint versehen, um zu sehen, was genau schief läuft (sonst geht die eigentliche Exception verloren):
Code: Alles auswählen
static SWIGExceptionHelper() {
try {
SWIGRegisterExceptionCallbacks_Assimp(
applicationDelegate,
arithmeticDelegate,
divideByZeroDelegate,
indexOutOfRangeDelegate,
invalidCastDelegate,
invalidOperationDelegate,
ioDelegate,
nullReferenceDelegate,
outOfMemoryDelegate,
overflowDelegate,
systemDelegate);
SWIGRegisterExceptionCallbacksArgument_Assimp(
argumentDelegate,
argumentNullDelegate,
argumentOutOfRangeDelegate);
}
catch (Exception e) {
throw new ApplicationException(e.Message); // hier einen Breakpoint setzen
}
}
Die Meldung der Exception gibt dann Auskunft darüber, warum der Aufruf in die Bibliothek gescheitert ist.
Ich hoffe, damit dem einen oder anderen ein, zwei schlaflose Nächte weniger zu bereiten :)
Gruß
mOfl