Wie verknüpfen Sie C # - und C ++ - Assemblies zu einer einzigen ausführbaren Datei?

9

Ich habe eine VS2008-Lösung, die ein Projekt enthält, das eine C # -Datei generiert, die auf ein Projekt verweist, das eine DLL generiert, die C ++ / CLI und nicht verwaltetes C ++ enthält.

Ich möchte diese in eine einzelne ausführbare Datei zusammenführen, da die C ++ - DLL Sicherheitscode enthält, den ich in die Hauptdatei einbetten möchte.

Ich kann ILMerge nicht verwenden, da die DLL sowohl verwalteten als auch nicht verwalteten Code enthält. Die vorgeschlagene Lösung scheint zu sein, Link.exe zu verwenden, um die C # -Assembly mit den C ++ - Objektdateien zu verknüpfen. Das ist, was ich versuche zu tun.

Ich habe die Projektdatei für die ausführbare Datei c # manuell bearbeitet, um ein Netmodul zu erzeugen. Ich fügte dem ausführbaren Projekt einen Post-Build-Schritt hinzu, um link.exe auszuführen, um das c # -Netzmodul und die kompilierten C ++ - Objektdateien miteinander zu verknüpfen, und dann mt.exe auszuführen, um die von beiden Projekten erstellten Assembly-Manifeste zusammenzuführen. Dies wird erfolgreich ausgeführt, aber die Exe enthält immer noch einen Verweis auf und verwendet die C ++ - Typen, die in der DLL definiert sind, die vom normalen Erstellungsprozess für das C ++ - Projekt generiert wird.

Ich habe dann / NOASSEMBLY in den Projekteinstellungen für die C ++ - DLL angegeben, also erzeugt es auch ein Netmodul. Im C # -Projekt habe ich den Verweis auf das C ++ - Projekt entfernt, aber eine Projektabhängigkeit in die Lösung eingefügt. Ich habe die C # -Projektdatei wie folgt ähnlich bearbeitet:

%Vor%

d. um auf das C ++ - Netmodul zu verweisen, das jetzt vom C ++ - Projekt generiert wird.

Der Linker-Schritt in meinem Post-Build-Ereignis schlägt jedoch mit folgendem Fehler fehl:

%Vor%

Das ist völlig verständlich, da ich nicht im bibliothekcode-netmodul verlinke; Ich verbinde stattdessen in den C ++ - Objektdateien, die zum Generieren des Netmoduls verwendet werden.

Kurz gesagt, wie füge ich eine c # ausführbare Datei und C ++ - Objektdateien in eine einzelne Assembly ein? Was habe ich verpasst?

Meine bisherige Referenzquelle (appart von der Link.exe-Befehlsverknüpfungsreferenz usw. auf MSDN) sind die zwei folgenden Artikel:

Vielen Dank im Voraus.

Update1

Ich bin genau dem Beispiel in Steve Teixeiras Blog gefolgt und habe mir vergewissert, dass es funktioniert. Mit Reflector kann ich sehen, dass die resultierende ausführbare Datei zwei Netmodule enthält. Das c # netmodul enthält einen Verweis auf ein anderes Netmodul, aber keinen Namen ?! Wenn Sie die Assembly in ein neues Verzeichnis verschieben, wird das zweite Netmodul (offensichtlich) nicht referenziert, aber die ausführbare Datei wird weiterhin ausgeführt, da Typen mit der richtigen Definition im c # -Netzwerk vorhanden sind.

Beachten Sie, dass das ursprüngliche c # -Netzwerkmodul einen benannten Verweis auf das C ++ - Netmodul enthält. Daher muss es der Linkerschritt sein, der den Namen entfernt.

Wenn ich versuche, diesem Beispiel in meinem Beispielprojekt zu folgen, habe ich meinem Post-Build-Linker-Schritt das Argument / ASSEMBLYMODULE hinzugefügt. Der Linker schlägt jetzt mit

fehl %Vor%

Ich vermute, dass es die Linker-Magie ist, die den Modul-Referenznamen entfernt, den ich vermisse.

Irgendwelche Ideen willkommen.

Update2

Ich habe mein Projekt auf das Einfachste reduziert und versuche, es von der Kommandozeile aus zu kompilieren. Die folgende Stapeldatei erstellt erfolgreich das Beispiel in Steve Teixeiras Blog:

%Vor%

Die folgende Stapeldatei kann meinen Beispielcode mit dem Linkerfehler LNK2022 nicht erstellen:

%Vor%

Zeit für den Unterschied: - (

    
swingkid 09.04.2010, 16:17
quelle

3 Antworten

2

Das folgende ist ein Nant-Build-Skript, das genau das tut, was Sie (und ich) wollten (wenn ich Ihr Wunschrecht lese, das xD ist).

Einige davon fehlen (wie einige Variablen, die nicht wirklich benötigt werden), aber es stellte sich heraus, dass sie ziemlich einfach zu erreichen sind.

Dies zeigt die cl / csc- und linker-Flags, die Sie benötigen, um eine gemischte und eine verwaltete Assembly zusammenführen zu können. Als zusätzlicher "Bonus" sind alle internen Klassen / Methoden / Felder usw. innerhalb der gesamten neuen Assembly sichtbar, dh sie überschreiten die Grenzen des Projekts.

%Vor%     
Alxandr 19.10.2012 03:22
quelle
0

Ihr Geschäftsfall ist SQLite sehr ähnlich, daher sollte der gleiche Ansatz für Sie funktionieren. Im Grunde fügen sie die verwaltete Assembly als separaten Datenabschnitt in die nicht verwaltete DLL ein. Sie sind dann in der Lage, die unmanaged DLL von der verwalteten DLL auf normale Weise aufzurufen / aufzurufen. Es ist auch möglich, dynamisch mit dem nicht verwalteten Code in der DLL zu verknüpfen.

    
Anton Tykhyy 12.04.2010 08:40
quelle
0

Um korrekt zusammengeführt zu werden, sollte program.netmodule in Linker zweimal in der Eingabeliste und als Parameter in der ASSEMBLYMODULE-Option angegeben werden.

Also wird die gesamte Befehlszeile wie folgt aussehen:

%Vor%

Nach dieser Befehlszeile sollten die program.module-Typen in MixedLanguageDemo.exe zusammengeführt werden. Sie können jederzeit überprüfen, was mit .NET-Reflektoren in Ihre resultierende Baugruppe gelangt, z. B. ILSpy oder Telerik .

Glückliche Kodierung.

    
Anton K 14.08.2014 01:42
quelle

Tags und Links