Laden...

Zielkonvertierung klappt nicht...

Erstellt von Hank-ER vor 18 Jahren Letzter Beitrag vor 18 Jahren 6.430 Views
H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren
Zielkonvertierung klappt nicht...

Hallo,
ich habe noch ein Problem mit meiner Anwendung.

Ich mache einen Methodenaufruf in einer anderen dll und übergebe als Parameter ein object-Array mit zwei Objekten drin.
In der entfernten Methode klappt die Zielkonvertierung der Typen jedoch nicht. Und das obwohl die Klassen vom Code sogar identisch sind.
Wenn ich in der entfernten Methode object als Typ für die beiden übergebenen Parameter angebe, funktioniert die Sache natürlich - ich möchte aber mit den übergebenen object was anfangen können.

Das ist der Aufruf der entfernten dll:

public void InvokeMethode(string assembly, string type, string methode, object[] parameters)
		{
			// Create object from assembly
			//Console.WriteLine("hier1");
			Assembly myAssembly = System.Reflection.Assembly.LoadFrom(assembly);
			//Console.WriteLine("hier2");
			//Console.WriteLine(assembly);
			//Console.WriteLine(type);
			//Console.WriteLine(methode);
			//PrintValues(parameters);
			Console.WriteLine("hier3");
			Console.WriteLine(parameters[0].ToString());
			Console.WriteLine(parameters[1].ToString());
			Console.WriteLine("hier3");
			object myObj = myAssembly.CreateInstance(type);
			Console.WriteLine("object");
			Console.WriteLine(myObj.ToString());
			Console.WriteLine("/object");
			// Invode methode
			Type myTypea = myObj.GetType();
			MethodInfo myMethodinfoa = myTypea.GetMethod(methode);
			myMethodinfoa.Invoke(myObj, parameters);
			//Console.WriteLine("zurueckbekommes object");
			//Console.WriteLine(o.ToString());
			Console.WriteLine("/object");
			//object myObj2 =	myMethodinfoa.Invoke(myObj, null);
			//Type myTypeb = myObj2.GetType();

			//Console.WriteLine(myObj2.ToString());
			//Console.WriteLine(myTypeb.ToString());
			//MessageBox.Show(myObj2);
			//System.Windows.Forms.UserControl uc = (System.Windows.Forms.UserControl)myObj2;
			//testTab = new System.Windows.Forms.TabPage();

			//testTab.Controls.Add(uc);
			//tabControl1.Controls.Add(testTab);

			


		}

		public void LoadAssemblyNow(string filename)
		{
			//MessageBox.Show("Assembly auswählen, escht jetz!!!", filename);
			//OpenFileDialog myDiag = new OpenFileDialog();
			//myDiag.ShowDialog();

			
			string gstring = "Haaallooo!";
			Console.WriteLine(gstring);
			Console.WriteLine(filename);
			System.Windows.Forms.Form testform = new System.Windows.Forms.Form();
			InvokeMethode(filename, "TestAssembly.Class1", "getUserControl", new object[]{ this, stick } );

		}

Hier ist die aufgerufene Methode in der entfernten dll:

public void getUserControl(MainWindow mw, IScatterFlasher sf)
		{
			
			//ScatterFlasher.TabPage1 tp = new ScatterFlasher.TabPage1(sticky);
			System.Windows.Forms.Form m = (System.Windows.Forms.Form)mw;
			//IScatterFlasher stick = (ScatterFlasher.IScatterFlasher)sf;
			Type myTypea = sf.GetType();
			Console.WriteLine("type");
			Console.WriteLine(myTypea);

			Console.WriteLine("/type");
			Console.WriteLine("m");
			Console.WriteLine(m.ToString());
			Console.WriteLine(sf.ToString());
			Console.WriteLine("/m");
			mw.Controls.Add(new System.Windows.Forms.TabPage());
			//return tp;
			
		}

Die Konsolenausgabe sieht so aus:

'DefaultDomain': 'c:\windows\microsoft.net\framework\v1.1.4322\mscorlib.dll' geladen, keine Symbole geladen.
'ScatterFlasher': 'c:\windows\assembly\gac\mscorlib.resources\1.0.5000.0_de_b77a5c561934e089\mscorlib.resources.dll' geladen, keine Symbole geladen.
'ScatterFlasher': 'E:\studium\sensorweb\programmieren\aktuell\09.07.05\bin\Debug\ScatterFlasher.exe' geladen, Symbole geladen.
'ScatterFlasher.exe': 'c:\windows\assembly\gac\system.windows.forms\1.0.5000.0__b77a5c561934e089\system.windows.forms.dll' geladen, keine Symbole geladen.
'ScatterFlasher.exe': 'c:\windows\assembly\gac\system\1.0.5000.0__b77a5c561934e089\system.dll' geladen, keine Symbole geladen.
'ScatterFlasher.exe': 'c:\windows\assembly\gac\system.drawing\1.0.5000.0__b03f5f7f11d50a3a\system.drawing.dll' geladen, keine Symbole geladen.
number of Files found:
..\..\applications\application.dll
Haaallooo!
..\..\applications\application.dll
'ScatterFlasher.exe': 'e:\studium\sensorweb\programmieren\aktuell\09.07.05\applications\application.dll' geladen, Symbole geladen.
hier3
ScatterFlasher.MainWindow, Text:
ScatterFlasher.Dummie
hier3
object
TestAssembly.Class1
/object
The process failed: System.ArgumentException: Der Objekttyp kann nicht zum Zieltyp konvertiert werden.
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean verifyAccess)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at ScatterFlasher.MainWindow.InvokeMethode(String assembly, String type, String methode, Object[] parameters) in e:\studium\sensorweb\programmieren\aktuell\09.07.05\main.cs:line 1497
at ScatterFlasher.MainWindow.LoadAssemblyNow(String filename) in e:\studium\sensorweb\programmieren\aktuell\09.07.05\mDer Thread 'LoadFileThread' (0x638) hat mit Code 0 (0x0) geendet.
Der Thread 'afterStart Thread' (0x504) hat mit Code 0 (0x0) geendet.
Der Thread 'scanThread' (0x8e8) hat mit Code 0 (0x0) geendet.
ain.cs:line 1529
at ScatterFlasher.ConDisconTabPage.searchnexAppdll(String searchstring) in e:\studium\sensorweb\programmieren\aktuell\09.07.05\condiscontabpage.cs:line 403
Sending tiz: tiz 5-7-11 14:25:19
'ScatterFlasher.exe': 'c:\windows\assembly\gac\system.xml\1.0.5000.0__b77a5c561934e089\system.xml.dll' geladen, keine Symbole geladen.
Called this.Close()

Wie gesagt, wenn ich in der Methode 'getUserControl' object als Parametertyp wähle funktioniert das ja, aber ich kann mit einfachen Objekten nichts anfangen Casting auf ursprünglichen Typ klappt auch nicht...

S
8.746 Beiträge seit 2005
vor 18 Jahren

Der Default-Binder kann nur einen übergebenen Parameter in den Basistypen (!!!!) casten (bei dir Windows.Form), oder in ein Interface.

Du kannst also nicht MainWindow in getUserControl() angeben, sondern nur Form.

Alternative: Baue einen Custom Binder (würg), oder verwende für den Zugriff auf dein Fenster ebenfalls ein Interface (wohl einfacher und klarer).

H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren

Ok, danke - so etwas hatte ich schon vermutet.
Also das mit dem Fenster ist kein Problem - habe ich schon beseitigt, indem ich einfach nur den TabControl übergebe - da kann da das Fenster eingefügt werden.
Was das andere betrifft - IScatterFlasher IST ein Interface. trotzdem scheint das nicht zu klappen.
Also es sieht so aus:
Das übergebene zweite Argument (stick) ist vom Typ Dummie, der das Interface IScatterFlasher implementiert. Dummie erbt zusätzlich von der abstrakten Klasse ComBase - vielleicht ist das ja das Problem...???

S
8.746 Beiträge seit 2005
vor 18 Jahren

Ich vermute, dass er dein Fenster nicht binden kann, das Interface wird ihm keine Probleme bereiten. Mach doch mal aus dem 1. Parametertyp ein "Form" statt "ManWindow", sollte klappen, nur mal so zum Test.

H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren

Das scheint es nicht zu sein - die selbe Fehlermeldung. Habe nun statt dem Fenster nur das TabControl übergeben und auf der anderen Seite als Typ System.Windows.Forms.TabControl benutzt. Es liegt wirklich am zweiten Parameter.

S
8.746 Beiträge seit 2005
vor 18 Jahren

Ratlosigkeit....

P
939 Beiträge seit 2003
vor 18 Jahren

Vielleicht wird das IScatterFlasher-Interface, in das gecastet werden soll, nicht gefunden oder es gibt es zweimal.

In welcher Assembly ist es definiert, in der Exe oder in der Dll? Da die Dll das Interface verwendet, müsste es eigentlich in der Dll sein (aber nicht nochmal in der Exe).

Gruss
Pulpapex

H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren

Ja, das könnte sein. Es ist sowohl in der Exe als auch in der Dll definiert. Ich brauche es aber an beiden Orten - wie kann ich das machen?

S
8.746 Beiträge seit 2005
vor 18 Jahren

Bei Interfaces, die von PlugIns benutzt werden. sollte man die Interfaces selbst in ein eigenes Assembly auslagern.

P
939 Beiträge seit 2003
vor 18 Jahren

Du brauchst eine dritte Assembly, in der IScatterFlasher definiert ist. Sowohl die Exe als auch die Plugin-Dlls verwenden diese Dll. Sie muss unabhängig sein, d.h. sie muss sowohl die Interfaces als verwendete Parametertypen enthalten.

Assembly-Abhängigkeiten:

[App.exe] ---------> [Interface.dll] <--------- [Plugin.dll]
           depends                     depends
H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren

Hmmm, ok, das kann ich machen - und dann kann ich es trotzdem in der exe nutzen oder meinst du ich soll dann die dll, wo das Interface beschrieben ist bei Verweise hinzufügen, sowohl in der exe, als auch in der dll?
Sorry, bin noch frisch bei C#...

P
939 Beiträge seit 2003
vor 18 Jahren

Die Interface-Definition in der Exe muss weg. Verweise hinzufügen ist der richtige Weg. 😉

S
8.746 Beiträge seit 2005
vor 18 Jahren

Wo wir grad beim Thema sind, hier eine sehr abgefahrene Lösung, die miese Performance bei Methodenaufrufen bei später Bindung zu verbessern:

Frisch aus CodeProject:

http://www.codeproject.com/csharp/DynamicMethodDelegates.asp

H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren

Believe it or not - it works!!!!!!! 😁 👍

H
Hank-ER Themenstarter:in
16 Beiträge seit 2005
vor 18 Jahren

Danke schön an die beiden hervorragenden Experten 👍 👍 👍