2009-05-26 6 views
6

Ich habe eine .NET-DLL, die einige Schnittstellen \ Klassen, die com ausgesetzt sind. Während der Erstellungsprozedur wird eine TLB-Datei generiert und auf diese TLB wird durch einen C++ - Code verwiesen. Als Ergebnis erzeugt der Compiler eine TLH-Datei für die TLB..tlh generiert auf 2 Maschinen ist anders

Wenn ich den Build lokal ausführen, endet eine der Eigenschaften in einer der Schnittstellen mit einer entsprechenden Methode in der TLH, die nicht den gleichen Namen hat. Die Eigenschaft in dem .NET-Code wird als PropertyA bezeichnet und heißt get_propertyA, während PropertyB mit dem Namen get_PropertyB endet. Ich habe kein Auge zugedrückt, als dies passierte, habe einfach die Methode wie in der TLH definiert verwendet und angenommen, dass alles gut war, aber als ich diese Änderungen vorgenommen habe, funktionierte der Build für niemanden sonst, da der Compiler Eigenschaften namens get_PropertyA und get_PropertyB (Kündigungsfall bei PropertyA).

Die auf beiden Rechnern erzeugten tlb-Dateien sind identisch (nach einem Hex-Vergleich) und die tlh-Dateien werden beide von der gleichen Compiler-Version erzeugt.

Die Build-Prozedur erstellt den TLB, indem Sie: path \ to \ mydll.tlb Ausgabe \

Irgendwelche Ideen, warum meine lokale Version endet mit einer Eigenschaft: regasm Pfad \ dll \ Mydll.dll -tlb \ mit dem falschen Namen? Oder was kann ich tun, um es zu reparieren?

UPDATE: Ich habe gelesen, dass tlbexp die erste Version der Zeichenfolge verwenden wird, die es findet und die mit einer Neukompilierung ändern kann. Obwohl ich tlbexp nicht verwende, habe ich mich gefragt, ob das das Problem war. Ich fand Parameter mit dem gleichen Namen wie meine Methode (in anderen Methoden), aber mit einem Kleinbuchstaben am Anfang. Also habe ich all diese ersetzt. Neu gebaut, keine Veränderung. SO habe ich dann meine COM-Methode umbenannt. Re-Built und hat die erwarteten fehlenden Methodenfehler erhalten. Die Methode wurde wieder in den ursprünglichen Namen umbenannt, und hey presto schien es behoben zu sein. Da es jetzt zu funktionieren scheint und ich es nicht wieder zum Scheitern bringen kann, kann ich die vorgeschlagenen Lösungen nicht ausprobieren, aber ich mag die Umbenennungsidee, falls dies in der Zukunft passieren sollte.

+0

Seien Sie vorsichtig, wenn Sie die Umgehung "Umbenennen" verwenden - es funktioniert wie eine einfache Textersetzung und kann manchmal zu seltsamen Ergebnissen führen. Ich habe die Antwort aktualisiert, um das zu skizzieren. – sharptooth

+0

danke für die heads-up. Ich werde das berücksichtigen, wenn Probleme auftauchen. –

Antwort

4

Sie können das Umbenennen Attribut für den Import verwenden, um die Eigenschaften explizit umzubenennen. Angenommen, Sie haben propA, was manchmal zu PropA und propB wird, was manchmal zu PropB wird. Um immer PropA und PropB Verwendung haben umbenennen wie folgt:

#import <library> rename("propA", "PropA") rename("propB", "PropB") 

Verwenden Sie diese mit Sorgfalt - es verursacht eine einfache Textersetzung, die für alle Kennungen funktioniert es in der Typbibliothek trifft. In einigen Fällen kann es schwierig sein, unerwünschte Nebenwirkungen zu beseitigen.

+0

Kann nicht testen, ob dies das Problem behebt (siehe Update in Frage oben), aber es scheint, als könnte es wahrscheinlich nicht als Antwort akzeptieren, aber ich habe es upvolotiert. Wenn das Problem zurückkommt, werde ich es versuchen und zurückkommen.Danke für den Vorschlag –

+0

Ok, so kam das Problem zurück. Ich habe das getestet und es scheint gut zu funktionieren. Vielen Dank! –

+0

Ich habe nicht downvote, da dies funktioniert, aber das zwingt Sie, jedes Mal, wenn Sie die Bibliothek importieren, eine Umbenennung vorzunehmen. Wäre es nicht besser, die korrekte Erstellung der tlb an erster Stelle zu erzwingen (siehe/Namen auf tlbexp) –

0

Gesundheitsüberprüfung: Sind Sie absolut sicher, dass die gleiche # Importanweisung auf beiden Maschinen verwendet wird? d.h. dieselben Quelldateien, die kompiliert werden?

Versuchen Sie, eine Netzwerkfreigabe über das Verzeichnis zu erstellen, das das Projekt enthält, und öffnen Sie es auf der anderen Maschine, um 1000% sicher zu sein, dass es sich um dieselben Quelldateien handelt, die kompiliert werden.

Entschuldigung, ich habe keine spezifischeren Vorschläge.

+0

Ja, wir haben die Plausibilitätsprüfung bestanden. Die gleichen Dateien werden kompiliert, wir haben die cvs Versionsnummern überprüft. und wir haben überprüft, dass die Zwischenschritte die korrekten Dateien erzeugen (die TLB-Dateien sind identisch) und die Eigenschaften wurden in dieser Version neu eingeführt (umbenannt), so dass die Tatsache, dass sie überhaupt erscheinen, anzeigt, dass sie die richtige Quelle benutzt. .. –

+0

Können Sie die von Ihnen verwendete #import-Zeile posten? –

+0

#import raw_interfaces_only, raw_native_types, no_namespace, named_guids –

4

Ich habe das gleiche Problem.

Über eine weitere Frage SO (https://stackoverflow.com/questions/708721/compare-type-libraries-generated-by-tlbexp) fand ich dieses Stück Community-Inhalt:

http://social.msdn.microsoft.com/Forums/en-US/clr/thread/5003c486-ed3f-4ec8-8398-a1251b0f9e74

von diesem Inhalt Zitiert:

In der Dokumentation von TlbExp, ist man dort nützliche Gemeinschaft Inhalt:

http://msdn2.microsoft.com/en-gb/library/hfzzah2c(VS.80).aspx

"Der Grund für die Option/Names ist, dass Typbibliotheken jede Kennung in einer Tabelle ohne Berücksichtigung der Groß- und Kleinschreibung speichern. Der erste gefundene Fall gewinnt. Eine Klasse namens Monitor könnte also als "Monitor" angezeigt werden, wenn ein Parameter mit einem solchen Namen zuerst gefunden wird. . (! Und die Reihenfolge, in der Bezeichner auftreten können einfach ändern sich je nach Ihrer Assembly neu zu kompilieren)/Namen stabilen Gehäuse garantieren können“

Die Ursache scheint ein Fehler in der midl zu sein, hier beschrieben:

http://support.microsoft.com/default.aspx?scid=kb;en-us;220137

Zitat:

„Wenn es zwei Kennungen, die nur von Fall zu unterscheiden, wird der Fall der zweiten Kennung geändert, den Fall der ersten zu reflektieren“

so als Lösung, ich unch die Option "für COM-Interop registrieren" in den Projekteinstellungen aktiviert und die Post-Build-Schritte hinzugefügt

"$ (DevEnvDir) .... \ SDK \ v2.0 \ Bin \ tlbexp" $ (TargetFileName)/names: "$ (ProjectDir) Names.txt" % windir% \ Microsoft.NET \ Framework \ v2.0.50727 \ regasm $ (TargetFileName)

Die Names-Datei enthält die Einträge, die festlegen, wie die Capizalisierung durchgeführt werden soll. In meinem Fall enthält es nur eine Zeile:

ID

Mit freundlichen Grüßen

Bernd Ritter

Mit dem/Namen dieses Problem für mich gelöst.

+0

danke für das Update, trotz der alten Frage. +1 für einen alternativen Ansatz. –

Verwandte Themen