Autor
|
Thema: Late Binding mit C# (2670 mal gelesen)
|
Tom12345 Mitglied
Beiträge: 2 Registriert: 30.08.2010
|
erstellt am: 30. Aug. 2010 16:49 <-- editieren / zitieren --> Unities abgeben:
Hallo! Ich programmiere nun schon länger mit C# und habe schon einige nette Dinge damit in Catia CAD/CAM machen können - nun wollte ich aufgrund dem Buch vom Jens Hansen einmal mit Late Binding beginnen und bin nun dran eine bereits laufende Funktion mit LB neu zu schreiben. Nun habe ich das Problem dass bei der Methode AxisSystem.GetOrigin(array) das array mit LB nicht gefüllt wird.. Hier ist ein Code-Ausschnitt der die Funktion darstellen sollte: object CATIA = System.Runtime.InteropServices.Marshal.GetActiveObject("catia.application"); object LB_Document = LbGet(CATIA, "ActiveDocument", null); if (!LbGet(LB_Document, "FullName", null).ToString().EndsWith("CATPart")) return (-1); object LB_PartDoc = LbGet(LB_Document, "Part", null); string AxisName = "AxisSystem.3"; object LB_AxisSystems = LbGet(LB_PartDoc, "AxisSystems", null); object LB_AxisSystem = LbMethod(LB_AxisSystems, "GetItem", new object[] { AxisName }); object[] LB_AxisOrigin = new object[3]; object[] args = new object[] { LB_AxisOrigin }; LbMethod(LB_AxisSystem, "GetOrigin", args); LbMethod läuft durch, LB_AxisOrigin[i] bleibt allerdings null. Hier ist noch LbMethod: private object LbMethod(object obj, string Command, object[] Args) { return(obj.GetType().InvokeMember(Command, BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, obj, Args)); } Über die Com-Bibliotheken funktioniert das einweindfrei und ich habe keine Ahnung was ich hier mit Late Binding falsch mache.. Hoffentlich könnt Ihr mir da weiterhelfen! Gruss Tom
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
gladly Mitglied
Beiträge: 56 Registriert: 02.11.2007 Catia V5R19SP9HF40 64Bit Windows XP Pro x64
|
erstellt am: 19. Okt. 2010 15:04 <-- editieren / zitieren --> Unities abgeben: Nur für Tom12345
Guten Tag, ich habe eine Lösung gefunden (wenn auch noch nicht ganz Optimal). Also das implizite Late-Binding von VB.net führt zu einem korrekten ergebnis. Woran das allerdings liegt kann ich noch nicht feststellen. Habe schon diverse Dinge probiert. Da C# ab der 2010er Version auch implizites Late-Binding unterstützen soll, rate ich dir einfach es erst einmal so zu machen! Aber zwingend halt fürs .net Framwork 4 (!) dann erstellen. Ich werde mich melden, wenn er herausgefunden habe, was bei der implizieten Variante "besser" gemacht wird. Übrigends ist die impliziete Variante aber keine vollkommene Lösung, was ein anderer Thread zeigt, in dem die impliziete nicht ging, dafür aber die Manuelle! mfg gladly [Diese Nachricht wurde von gladly am 19. Okt. 2010 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
gladly Mitglied
Beiträge: 56 Registriert: 02.11.2007 Catia V5R19SP9HF40 64Bit Windows XP Pro x64
|
erstellt am: 19. Okt. 2010 16:10 <-- editieren / zitieren --> Unities abgeben: Nur für Tom12345
So Problem gelöst... Habe es allerdings in VB gelöst, aber das kurz zmzuschreiben sollte kein Problem sein! Wichtig ist eigentlich das die ParameterModifier gesetzt werden. Musst also deine LbMethod ergänzen. Schreibe dort die ParameterModifier definition mit rein und erweitere den aufruf analog meinem - also noch "param, null, null" in deinen InvokeMember. Als nächstes musst du das ObjectArray (welches die Argumente zusammenfasst) vorher explizit diklarieren - siehe bei mir "dim args" Das ergebnis ist im args(0) drin, NICHT aber im original "coo" also noch coo = args(0) und du hast deine Coordinaten! Wieso er ein anscheinend neues Object in das Array als Rückgabewert packt verstehe ich aber noch nicht ganz... Hoffe ich konnte dir helfen. Code:
public shared sub main() '... Dim coo(2) As Object Dim args As Object() = {coo} Dim blaj As Object = CallMethod(axis2,"GetOrigin",args) coo = args(0) end sub Public Shared Function CallMethod(target As Object, methodName As String, ParamArray args As Object()) As Object dim bf as BindingFlags = BindingFlags.[Public] Or BindingFlags.NonPublic Or BindingFlags.InvokeMethod Or BindingFlags.Instance Dim p As New ParameterModifier(args.GetUpperBound(0)+1) '.Count) For i = 0 To args.GetUpperBound(0) '.Count - 1 p(i) = True Next Dim mods() As ParameterModifier = {p} Return InvokeMember(target.[GetType](), target, methodName, bf, mods, args) End Function Private Shared Function InvokeMember(type As Type, target As Object, memberName As String, flags As BindingFlags, mods as ParameterModifier(), ParamArray args As Object()) As Object Return type.InvokeMember(memberName, flags, nothing, target, args, mods, nothing, nothing) End Function
EDIT: Was ich vergessen hatte zu erwähnen. Die geänderte Funktion aber wirklich nur für Methoden nutzen, die ausschließlich Parameter als Referenz haben. Für alle anderen Aufrufe weiterhin deine Version nutzen. [Diese Nachricht wurde von gladly am 20. Okt. 2010 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Tom12345 Mitglied
Beiträge: 2 Registriert: 30.08.2010
|
erstellt am: 11. Nov. 2010 14:35 <-- editieren / zitieren --> Unities abgeben:
Hallo gladly! Vielen Dank für deine hilfreiche Antwort! Ohne sie wäre ich nicht mehr weiter gekommen und hätte das Thema Late binding vergessen können! Grüsse Tom Falls noch jemand den übersetzten C# code benötigt: { ... object[] Params = new object[] { new object[3] }; LbMethodGetParams(LB_AxisSystem, "GetOrigin", Params); } private object LbMethodGetParams(object obj, string Command, object[] Args) { ParameterModifier pm = new ParameterModifier(Args.GetUpperBound(0) + 1); for (int i = 0; i <= Args.GetUpperBound(0); i++) pm[i] = true; return (obj.GetType().InvokeMember(Command, BindingFlags.InvokeMethod | BindingFlags.OptionalParamBinding, null, obj, Args, new ParameterModifier[] { pm }, null, null)); }
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|